addons-contrib: objects.link/unlink syntax update
[blender-addons-contrib.git] / io_atomblend_utilities / io_atomblend_utilities.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 import os
20 import bpy
21 import bmesh
22 from mathutils import Vector
23 from math import sqrt
24 from copy import copy
25
26 # -----------------------------------------------------------------------------
27 #                                                         Atom and element data
28
29
30 # This is a list that contains some data of all possible elements. The structure
31 # is as follows:
32 #
33 # 1, "Hydrogen", "H", [0.0,0.0,1.0], 0.32, 0.32, 0.32 , -1 , 1.54   means
34 #
35 # No., name, short name, color, radius (used), radius (covalent), radius (atomic),
36 #
37 # charge state 1, radius (ionic) 1, charge state 2, radius (ionic) 2, ... all
38 # charge states for any atom are listed, if existing.
39 # The list is fixed and cannot be changed ... (see below)
40
41 ELEMENTS_DEFAULT = (
42 ( 1,      "Hydrogen",        "H", (  1.0,   1.0,   1.0), 0.32, 0.32, 0.79 , -1 , 1.54 ),
43 ( 2,        "Helium",       "He", ( 0.85,   1.0,   1.0), 0.93, 0.93, 0.49 ),
44 ( 3,       "Lithium",       "Li", (  0.8,  0.50,   1.0), 1.23, 1.23, 2.05 ,  1 , 0.68 ),
45 ( 4,     "Beryllium",       "Be", ( 0.76,   1.0,   0.0), 0.90, 0.90, 1.40 ,  1 , 0.44 ,  2 , 0.35 ),
46 ( 5,         "Boron",        "B", (  1.0,  0.70,  0.70), 0.82, 0.82, 1.17 ,  1 , 0.35 ,  3 , 0.23 ),
47 ( 6,        "Carbon",        "C", ( 0.56,  0.56,  0.56), 0.77, 0.77, 0.91 , -4 , 2.60 ,  4 , 0.16 ),
48 ( 7,      "Nitrogen",        "N", ( 0.18,  0.31,  0.97), 0.75, 0.75, 0.75 , -3 , 1.71 ,  1 , 0.25 ,  3 , 0.16 ,  5 , 0.13 ),
49 ( 8,        "Oxygen",        "O", (  1.0,  0.05,  0.05), 0.73, 0.73, 0.65 , -2 , 1.32 , -1 , 1.76 ,  1 , 0.22 ,  6 , 0.09 ),
50 ( 9,      "Fluorine",        "F", ( 0.56,  0.87,  0.31), 0.72, 0.72, 0.57 , -1 , 1.33 ,  7 , 0.08 ),
51 (10,          "Neon",       "Ne", ( 0.70,  0.89,  0.96), 0.71, 0.71, 0.51 ,  1 , 1.12 ),
52 (11,        "Sodium",       "Na", ( 0.67,  0.36,  0.94), 1.54, 1.54, 2.23 ,  1 , 0.97 ),
53 (12,     "Magnesium",       "Mg", ( 0.54,   1.0,   0.0), 1.36, 1.36, 1.72 ,  1 , 0.82 ,  2 , 0.66 ),
54 (13,     "Aluminium",       "Al", ( 0.74,  0.65,  0.65), 1.18, 1.18, 1.82 ,  3 , 0.51 ),
55 (14,       "Silicon",       "Si", ( 0.94,  0.78,  0.62), 1.11, 1.11, 1.46 , -4 , 2.71 , -1 , 3.84 ,  1 , 0.65 ,  4 , 0.42 ),
56 (15,    "Phosphorus",        "P", (  1.0,  0.50,   0.0), 1.06, 1.06, 1.23 , -3 , 2.12 ,  3 , 0.44 ,  5 , 0.35 ),
57 (16,        "Sulfur",        "S", (  1.0,   1.0,  0.18), 1.02, 1.02, 1.09 , -2 , 1.84 ,  2 , 2.19 ,  4 , 0.37 ,  6 , 0.30 ),
58 (17,      "Chlorine",       "Cl", ( 0.12,  0.94,  0.12), 0.99, 0.99, 0.97 , -1 , 1.81 ,  5 , 0.34 ,  7 , 0.27 ),
59 (18,         "Argon",       "Ar", ( 0.50,  0.81,  0.89), 0.98, 0.98, 0.88 ,  1 , 1.54 ),
60 (19,     "Potassium",        "K", ( 0.56,  0.25,  0.83), 2.03, 2.03, 2.77 ,  1 , 0.81 ),
61 (20,       "Calcium",       "Ca", ( 0.23,   1.0,   0.0), 1.74, 1.74, 2.23 ,  1 , 1.18 ,  2 , 0.99 ),
62 (21,      "Scandium",       "Sc", ( 0.90,  0.90,  0.90), 1.44, 1.44, 2.09 ,  3 , 0.73 ),
63 (22,      "Titanium",       "Ti", ( 0.74,  0.76,  0.78), 1.32, 1.32, 2.00 ,  1 , 0.96 ,  2 , 0.94 ,  3 , 0.76 ,  4 , 0.68 ),
64 (23,      "Vanadium",        "V", ( 0.65,  0.65,  0.67), 1.22, 1.22, 1.92 ,  2 , 0.88 ,  3 , 0.74 ,  4 , 0.63 ,  5 , 0.59 ),
65 (24,      "Chromium",       "Cr", ( 0.54,   0.6,  0.78), 1.18, 1.18, 1.85 ,  1 , 0.81 ,  2 , 0.89 ,  3 , 0.63 ,  6 , 0.52 ),
66 (25,     "Manganese",       "Mn", ( 0.61,  0.47,  0.78), 1.17, 1.17, 1.79 ,  2 , 0.80 ,  3 , 0.66 ,  4 , 0.60 ,  7 , 0.46 ),
67 (26,          "Iron",       "Fe", ( 0.87,   0.4,   0.2), 1.17, 1.17, 1.72 ,  2 , 0.74 ,  3 , 0.64 ),
68 (27,        "Cobalt",       "Co", ( 0.94,  0.56,  0.62), 1.16, 1.16, 1.67 ,  2 , 0.72 ,  3 , 0.63 ),
69 (28,        "Nickel",       "Ni", ( 0.31,  0.81,  0.31), 1.15, 1.15, 1.62 ,  2 , 0.69 ),
70 (29,        "Copper",       "Cu", ( 0.78,  0.50,   0.2), 1.17, 1.17, 1.57 ,  1 , 0.96 ,  2 , 0.72 ),
71 (30,          "Zinc",       "Zn", ( 0.49,  0.50,  0.69), 1.25, 1.25, 1.53 ,  1 , 0.88 ,  2 , 0.74 ),
72 (31,       "Gallium",       "Ga", ( 0.76,  0.56,  0.56), 1.26, 1.26, 1.81 ,  1 , 0.81 ,  3 , 0.62 ),
73 (32,     "Germanium",       "Ge", (  0.4,  0.56,  0.56), 1.22, 1.22, 1.52 , -4 , 2.72 ,  2 , 0.73 ,  4 , 0.53 ),
74 (33,       "Arsenic",       "As", ( 0.74,  0.50,  0.89), 1.20, 1.20, 1.33 , -3 , 2.22 ,  3 , 0.58 ,  5 , 0.46 ),
75 (34,      "Selenium",       "Se", (  1.0,  0.63,   0.0), 1.16, 1.16, 1.22 , -2 , 1.91 , -1 , 2.32 ,  1 , 0.66 ,  4 , 0.50 ,  6 , 0.42 ),
76 (35,       "Bromine",       "Br", ( 0.65,  0.16,  0.16), 1.14, 1.14, 1.12 , -1 , 1.96 ,  5 , 0.47 ,  7 , 0.39 ),
77 (36,       "Krypton",       "Kr", ( 0.36,  0.72,  0.81), 1.31, 1.31, 1.24 ),
78 (37,      "Rubidium",       "Rb", ( 0.43,  0.18,  0.69), 2.16, 2.16, 2.98 ,  1 , 1.47 ),
79 (38,     "Strontium",       "Sr", (  0.0,   1.0,   0.0), 1.91, 1.91, 2.45 ,  2 , 1.12 ),
80 (39,       "Yttrium",        "Y", ( 0.58,   1.0,   1.0), 1.62, 1.62, 2.27 ,  3 , 0.89 ),
81 (40,     "Zirconium",       "Zr", ( 0.58,  0.87,  0.87), 1.45, 1.45, 2.16 ,  1 , 1.09 ,  4 , 0.79 ),
82 (41,       "Niobium",       "Nb", ( 0.45,  0.76,  0.78), 1.34, 1.34, 2.08 ,  1 , 1.00 ,  4 , 0.74 ,  5 , 0.69 ),
83 (42,    "Molybdenum",       "Mo", ( 0.32,  0.70,  0.70), 1.30, 1.30, 2.01 ,  1 , 0.93 ,  4 , 0.70 ,  6 , 0.62 ),
84 (43,    "Technetium",       "Tc", ( 0.23,  0.61,  0.61), 1.27, 1.27, 1.95 ,  7 , 0.97 ),
85 (44,     "Ruthenium",       "Ru", ( 0.14,  0.56,  0.56), 1.25, 1.25, 1.89 ,  4 , 0.67 ),
86 (45,       "Rhodium",       "Rh", ( 0.03,  0.49,  0.54), 1.25, 1.25, 1.83 ,  3 , 0.68 ),
87 (46,     "Palladium",       "Pd", (  0.0,  0.41,  0.52), 1.28, 1.28, 1.79 ,  2 , 0.80 ,  4 , 0.65 ),
88 (47,        "Silver",       "Ag", ( 0.75,  0.75,  0.75), 1.34, 1.34, 1.75 ,  1 , 1.26 ,  2 , 0.89 ),
89 (48,       "Cadmium",       "Cd", (  1.0,  0.85,  0.56), 1.48, 1.48, 1.71 ,  1 , 1.14 ,  2 , 0.97 ),
90 (49,        "Indium",       "In", ( 0.65,  0.45,  0.45), 1.44, 1.44, 2.00 ,  3 , 0.81 ),
91 (50,           "Tin",       "Sn", (  0.4,  0.50,  0.50), 1.41, 1.41, 1.72 , -4 , 2.94 , -1 , 3.70 ,  2 , 0.93 ,  4 , 0.71 ),
92 (51,      "Antimony",       "Sb", ( 0.61,  0.38,  0.70), 1.40, 1.40, 1.53 , -3 , 2.45 ,  3 , 0.76 ,  5 , 0.62 ),
93 (52,     "Tellurium",       "Te", ( 0.83,  0.47,   0.0), 1.36, 1.36, 1.42 , -2 , 2.11 , -1 , 2.50 ,  1 , 0.82 ,  4 , 0.70 ,  6 , 0.56 ),
94 (53,        "Iodine",        "I", ( 0.58,   0.0,  0.58), 1.33, 1.33, 1.32 , -1 , 2.20 ,  5 , 0.62 ,  7 , 0.50 ),
95 (54,         "Xenon",       "Xe", ( 0.25,  0.61,  0.69), 1.31, 1.31, 1.24 ),
96 (55,       "Caesium",       "Cs", ( 0.34,  0.09,  0.56), 2.35, 2.35, 3.35 ,  1 , 1.67 ),
97 (56,        "Barium",       "Ba", (  0.0,  0.78,   0.0), 1.98, 1.98, 2.78 ,  1 , 1.53 ,  2 , 1.34 ),
98 (57,     "Lanthanum",       "La", ( 0.43,  0.83,   1.0), 1.69, 1.69, 2.74 ,  1 , 1.39 ,  3 , 1.06 ),
99 (58,        "Cerium",       "Ce", (  1.0,   1.0,  0.78), 1.65, 1.65, 2.70 ,  1 , 1.27 ,  3 , 1.03 ,  4 , 0.92 ),
100 (59,  "Praseodymium",       "Pr", ( 0.85,   1.0,  0.78), 1.65, 1.65, 2.67 ,  3 , 1.01 ,  4 , 0.90 ),
101 (60,     "Neodymium",       "Nd", ( 0.78,   1.0,  0.78), 1.64, 1.64, 2.64 ,  3 , 0.99 ),
102 (61,    "Promethium",       "Pm", ( 0.63,   1.0,  0.78), 1.63, 1.63, 2.62 ,  3 , 0.97 ),
103 (62,      "Samarium",       "Sm", ( 0.56,   1.0,  0.78), 1.62, 1.62, 2.59 ,  3 , 0.96 ),
104 (63,      "Europium",       "Eu", ( 0.38,   1.0,  0.78), 1.85, 1.85, 2.56 ,  2 , 1.09 ,  3 , 0.95 ),
105 (64,    "Gadolinium",       "Gd", ( 0.27,   1.0,  0.78), 1.61, 1.61, 2.54 ,  3 , 0.93 ),
106 (65,       "Terbium",       "Tb", ( 0.18,   1.0,  0.78), 1.59, 1.59, 2.51 ,  3 , 0.92 ,  4 , 0.84 ),
107 (66,    "Dysprosium",       "Dy", ( 0.12,   1.0,  0.78), 1.59, 1.59, 2.49 ,  3 , 0.90 ),
108 (67,       "Holmium",       "Ho", (  0.0,   1.0,  0.61), 1.58, 1.58, 2.47 ,  3 , 0.89 ),
109 (68,        "Erbium",       "Er", (  0.0,  0.90,  0.45), 1.57, 1.57, 2.45 ,  3 , 0.88 ),
110 (69,       "Thulium",       "Tm", (  0.0,  0.83,  0.32), 1.56, 1.56, 2.42 ,  3 , 0.87 ),
111 (70,     "Ytterbium",       "Yb", (  0.0,  0.74,  0.21), 1.74, 1.74, 2.40 ,  2 , 0.93 ,  3 , 0.85 ),
112 (71,      "Lutetium",       "Lu", (  0.0,  0.67,  0.14), 1.56, 1.56, 2.25 ,  3 , 0.85 ),
113 (72,       "Hafnium",       "Hf", ( 0.30,  0.76,   1.0), 1.44, 1.44, 2.16 ,  4 , 0.78 ),
114 (73,      "Tantalum",       "Ta", ( 0.30,  0.65,   1.0), 1.34, 1.34, 2.09 ,  5 , 0.68 ),
115 (74,      "Tungsten",        "W", ( 0.12,  0.58,  0.83), 1.30, 1.30, 2.02 ,  4 , 0.70 ,  6 , 0.62 ),
116 (75,       "Rhenium",       "Re", ( 0.14,  0.49,  0.67), 1.28, 1.28, 1.97 ,  4 , 0.72 ,  7 , 0.56 ),
117 (76,        "Osmium",       "Os", ( 0.14,   0.4,  0.58), 1.26, 1.26, 1.92 ,  4 , 0.88 ,  6 , 0.69 ),
118 (77,       "Iridium",       "Ir", ( 0.09,  0.32,  0.52), 1.27, 1.27, 1.87 ,  4 , 0.68 ),
119 (78,     "Platinium",       "Pt", ( 0.81,  0.81,  0.87), 1.30, 1.30, 1.83 ,  2 , 0.80 ,  4 , 0.65 ),
120 (79,          "Gold",       "Au", (  1.0,  0.81,  0.13), 1.34, 1.34, 1.79 ,  1 , 1.37 ,  3 , 0.85 ),
121 (80,       "Mercury",       "Hg", ( 0.72,  0.72,  0.81), 1.49, 1.49, 1.76 ,  1 , 1.27 ,  2 , 1.10 ),
122 (81,      "Thallium",       "Tl", ( 0.65,  0.32,  0.30), 1.48, 1.48, 2.08 ,  1 , 1.47 ,  3 , 0.95 ),
123 (82,          "Lead",       "Pb", ( 0.34,  0.34,  0.38), 1.47, 1.47, 1.81 ,  2 , 1.20 ,  4 , 0.84 ),
124 (83,       "Bismuth",       "Bi", ( 0.61,  0.30,  0.70), 1.46, 1.46, 1.63 ,  1 , 0.98 ,  3 , 0.96 ,  5 , 0.74 ),
125 (84,      "Polonium",       "Po", ( 0.67,  0.36,   0.0), 1.46, 1.46, 1.53 ,  6 , 0.67 ),
126 (85,      "Astatine",       "At", ( 0.45,  0.30,  0.27), 1.45, 1.45, 1.43 , -3 , 2.22 ,  3 , 0.85 ,  5 , 0.46 ),
127 (86,         "Radon",       "Rn", ( 0.25,  0.50,  0.58), 1.00, 1.00, 1.34 ),
128 (87,      "Francium",       "Fr", ( 0.25,   0.0,   0.4), 1.00, 1.00, 1.00 ,  1 , 1.80 ),
129 (88,        "Radium",       "Ra", (  0.0,  0.49,   0.0), 1.00, 1.00, 1.00 ,  2 , 1.43 ),
130 (89,      "Actinium",       "Ac", ( 0.43,  0.67,  0.98), 1.00, 1.00, 1.00 ,  3 , 1.18 ),
131 (90,       "Thorium",       "Th", (  0.0,  0.72,   1.0), 1.65, 1.65, 1.00 ,  4 , 1.02 ),
132 (91,  "Protactinium",       "Pa", (  0.0,  0.63,   1.0), 1.00, 1.00, 1.00 ,  3 , 1.13 ,  4 , 0.98 ,  5 , 0.89 ),
133 (92,       "Uranium",        "U", (  0.0,  0.56,   1.0), 1.42, 1.42, 1.00 ,  4 , 0.97 ,  6 , 0.80 ),
134 (93,     "Neptunium",       "Np", (  0.0,  0.50,   1.0), 1.00, 1.00, 1.00 ,  3 , 1.10 ,  4 , 0.95 ,  7 , 0.71 ),
135 (94,     "Plutonium",       "Pu", (  0.0,  0.41,   1.0), 1.00, 1.00, 1.00 ,  3 , 1.08 ,  4 , 0.93 ),
136 (95,     "Americium",       "Am", ( 0.32,  0.36,  0.94), 1.00, 1.00, 1.00 ,  3 , 1.07 ,  4 , 0.92 ),
137 (96,        "Curium",       "Cm", ( 0.47,  0.36,  0.89), 1.00, 1.00, 1.00 ),
138 (97,     "Berkelium",       "Bk", ( 0.54,  0.30,  0.89), 1.00, 1.00, 1.00 ),
139 (98,   "Californium",       "Cf", ( 0.63,  0.21,  0.83), 1.00, 1.00, 1.00 ),
140 (99,   "Einsteinium",       "Es", ( 0.70,  0.12,  0.83), 1.00, 1.00, 1.00 ),
141 (100,       "Fermium",       "Fm", ( 0.70,  0.12,  0.72), 1.00, 1.00, 1.00 ),
142 (101,   "Mendelevium",       "Md", ( 0.70,  0.05,  0.65), 1.00, 1.00, 1.00 ),
143 (102,      "Nobelium",       "No", ( 0.74,  0.05,  0.52), 1.00, 1.00, 1.00 ),
144 (103,    "Lawrencium",       "Lr", ( 0.78,   0.0,   0.4), 1.00, 1.00, 1.00 ),
145 (104,       "Vacancy",      "Vac", (  0.5,   0.5,   0.5), 1.00, 1.00, 1.00),
146 (105,       "Default",  "Default", (  1.0,   1.0,   1.0), 1.00, 1.00, 1.00),
147 (106,         "Stick",    "Stick", (  0.5,   0.5,   0.5), 1.00, 1.00, 1.00),
148 )
149
150 # The list 'ELEMENTS' contains all data of the elements and will be used during
151 # runtime. The list will be initialized with the fixed
152 # data from above via the class below (ElementProp). One fixed list (above),
153 # which cannot be changed, and a list of classes with same data (ELEMENTS) exist.
154 # The list 'ELEMENTS' can be modified by e.g. loading a separate custom
155 # data file.
156 ELEMENTS = []
157
158
159 # This is the class, which stores the properties for one element.
160 class ElementProp(object):
161     __slots__ = ('number', 'name', 'short_name', 'color', 'radii', 'radii_ionic')
162     def __init__(self, number, name, short_name, color, radii, radii_ionic):
163         self.number = number
164         self.name = name
165         self.short_name = short_name
166         self.color = color
167         self.radii = radii
168         self.radii_ionic = radii_ionic
169
170
171 # This function measures the distance between two selected objects.
172 def distance():
173
174     # In the 'EDIT' mode
175     if bpy.context.mode == 'EDIT_MESH':
176
177         atom = bpy.context.edit_object
178         bm = bmesh.from_edit_mesh(atom.data)
179         locations = []
180
181         for v in bm.verts:
182             if v.select:
183                 locations.append(atom.matrix_world * v.co)
184
185         if len(locations) > 1:
186             location1 = locations[0]
187             location2 = locations[1]
188         else:
189             return "N.A"
190     # In the 'OBJECT' mode
191     else:
192
193         if len(bpy.context.selected_bases) > 1:
194             location1 = bpy.context.selected_objects[0].location
195             location2 = bpy.context.selected_objects[1].location
196         else:
197             return "N.A."
198
199     dv = location2 - location1
200     dist = str(dv.length)
201     pos = str.find(dist, ".")
202     dist = dist[:pos+4]
203     dist = dist + " A"
204
205     return dist
206
207
208 def choose_objects(action_type,
209                    who,
210                    radius_all,
211                    radius_pm,
212                    radius_type,
213                    radius_type_ionic,
214                    sticks_all):
215
216     # For selected objects of all selected layers
217     if who == "ALL_IN_LAYER":
218         # Determine all selected layers.
219         layers = []
220         for i, layer in enumerate(bpy.context.scene.layers):
221             if layer == True:
222                 layers.append(i)
223
224         # Put all objects, which are in the layers, into a list.
225         change_objects_all = []
226         for atom in bpy.context.scene.objects:
227             for layer in layers:
228                 if atom.layers[layer] == True:
229                     change_objects_all.append(atom)
230     # For selected objects of the visible layer
231     elif who == "ALL_ACTIVE":
232         change_objects_all = []
233         # Note all selected objects first.
234         for atom in bpy.context.selected_objects:
235             change_objects_all.append(atom)
236
237     # This is very important now: If there are dupliverts structures, note
238     # only the parents and NOT the children! Otherwise the double work is
239     # done or the system can even crash if objects are deleted. - The
240     # chidlren are accessed anyways (see below).
241     change_objects = []
242     for atom in change_objects_all:
243         if atom.parent != None:
244             FLAG = False
245             for atom2 in change_objects:
246                 if atom2 == atom.parent:
247                    FLAG = True
248             if FLAG == False:
249                 change_objects.append(atom)
250         else:
251             change_objects.append(atom)
252
253     # And now, consider all objects, which are in the list 'change_objects'.
254     for atom in change_objects:
255         if len(atom.children) != 0:
256             for atom_child in atom.children:
257                 if atom_child.type in {'SURFACE', 'MESH', 'META'}:
258                     modify_objects(action_type,
259                                    atom_child,
260                                    radius_all,
261                                    radius_pm,
262                                    radius_type,
263                                    radius_type_ionic,
264                                    sticks_all)
265         else:
266             if atom.type in {'SURFACE', 'MESH', 'META'}:
267                 modify_objects(action_type,
268                                    atom,
269                                    radius_all,
270                                    radius_pm,
271                                    radius_type,
272                                    radius_type_ionic,
273                                    sticks_all)
274
275
276 # Modifying the radius of a selected atom or stick
277 def modify_objects(action_type,
278                    atom,
279                    radius_all,
280                    radius_pm,
281                    radius_type,
282                    radius_type_ionic,
283                    sticks_all):
284
285     # Modify atom radius (in pm)
286     if action_type == "ATOM_RADIUS_PM" and "Stick" not in atom.name:
287         if radius_pm[0] in atom.name:
288             atom.scale = (radius_pm[1]/100,) * 3
289
290     # Modify atom radius (all selected)
291     if action_type == "ATOM_RADIUS_ALL" and "Stick" not in atom.name:
292         atom.scale *= radius_all
293
294     # Modify atom radius (type, van der Waals, atomic or ionic)
295     if action_type == "ATOM_RADIUS_TYPE" and "Stick" not in atom.name:
296         for element in ELEMENTS:
297             if element.name in atom.name:
298                 # For ionic radii
299                 if radius_type == '3':
300                     charge_states = element.radii_ionic[::2]
301                     charge_radii =  element.radii_ionic[1::2]
302                     charge_state_chosen = int(radius_type_ionic) - 4
303
304                     find = (lambda searchList, elem:
305                             [[i for i, x in enumerate(searchList) if x == e]
306                             for e in elem])
307                     index = find(charge_states,[charge_state_chosen])[0]
308
309                     # Is there a charge state?
310                     if index != []:
311                         atom.scale = (charge_radii[index[0]],) * 3
312
313                 # For atomic and van der Waals radii.
314                 else:
315                     atom.scale = (element.radii[int(radius_type)],) * 3
316
317     # Modify atom sticks
318     if action_type == "STICKS_RADIUS_ALL" and ('Sticks_Cups' in atom.name or
319                                                'Sticks_Cylinder' in atom.name or
320                                                'Stick_Cylinder' in atom.name):
321
322         bpy.context.view_layer.objects.active = atom
323         bpy.ops.object.mode_set(mode='EDIT', toggle=False)
324         bm = bmesh.from_edit_mesh(atom.data)
325
326         locations = []
327         for v in bm.verts:
328             locations.append(v.co)
329
330         center = Vector((0.0,0.0,0.0))
331         center = sum([location for location in locations], center)/len(locations)
332
333         radius = sum([(loc[0]-center[0])**2+(loc[1]-center[1])**2
334                      for loc in locations], 0)
335         radius_new = radius * sticks_all
336
337         for v in bm.verts:
338             v.co[0] = ((v.co[0] - center[0]) / radius) * radius_new + center[0]
339             v.co[1] = ((v.co[1] - center[1]) / radius) * radius_new + center[1]
340
341         bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
342         bpy.context.view_layer.objects.active = None
343
344     # Replace atom objects
345     if action_type == "ATOM_REPLACE_OBJ" and "Stick" not in atom.name:
346
347         scn = bpy.context.scene.atom_blend
348
349         new_material = draw_obj_material(scn.replace_objs_material,
350                                          atom.active_material)
351
352         # Special object (like halo, etc.)
353         if scn.replace_objs_special != '0':
354             new_atom = draw_obj_special(scn.replace_objs_special, atom)
355             new_atom.parent = atom.parent
356         # Standard geomtrical objects
357         else:
358             # If the atom shape shall not be changed, then:
359             if scn.replace_objs == '0':
360                 atom.active_material = new_material
361                 return {'FINISHED'}
362             # If the atom shape shall change, then:
363             else:
364                 new_atom = draw_obj(scn.replace_objs, atom)
365                 new_atom.active_material = new_material
366                 new_atom.parent = atom.parent
367
368                 if "_repl" not in atom.name:
369                     new_atom.name = atom.name + "_repl"
370                 else:
371                     new_atom.name = atom.name
372
373         # Delete the old object.
374         bpy.ops.object.select_all(action='DESELECT')
375         atom.select_set(True)
376         bpy.ops.object.delete()
377         del(atom)
378
379     # Default shapes and colors for atoms
380     if action_type == "ATOM_DEFAULT_OBJ" and "Stick" not in atom.name:
381
382         scn = bpy.context.scene.atom_blend
383
384         # Create new material
385         new_material = bpy.data.materials.new("tmp")
386
387         # Create new object (NURBS sphere = '1b')
388         new_atom = draw_obj('1b', atom)
389         new_atom.active_material = new_material
390         new_atom.parent = atom.parent
391
392         # Change size and color of the new object
393         for element in ELEMENTS:
394             if element.name in atom.name:
395                 new_atom.scale = (element.radii[0],) * 3
396                 new_atom.active_material.diffuse_color = element.color
397                 new_atom.name = element.name
398
399                 name = atom.active_material.name
400                 if element.name+"_standard" in name:
401                     pos = name.rfind("_standard")
402                     if name[pos+9:].isdigit():
403                         counter = int(name[pos+9:])
404                         new_material.name = name[:pos]+"_standard"+str(counter+1)
405                     else:
406                         new_material.name = name+"_standard1"
407                 else:
408                     new_material.name = name+"_standard1"
409
410         # Finally, delete the old object
411         bpy.ops.object.select_all(action='DESELECT')
412         atom.select_set(True)
413         bpy.ops.object.delete()
414
415
416 # Separating atoms from a dupliverts strucutre.
417 def separate_atoms(scn):
418
419     atom = bpy.context.edit_object
420
421     # Do nothing if it is not a dupliverts structure.
422     if not atom.instance_type == "VERTS":
423        return {'FINISHED'}
424
425     bm = bmesh.from_edit_mesh(atom.data)
426     locations = []
427     for v in bm.verts:
428         if v.select:
429             locations.append(atom.matrix_world * v.co)
430
431     bm.free()
432     del(bm)
433
434     name  = atom.name
435     scale = atom.children[0].scale
436     material = atom.children[0].active_material
437
438     # Separate the vertex from the main mesh and create a new mesh.
439     bpy.ops.mesh.separate()
440     new_object = bpy.context.scene.objects[0]
441     # And now, switch to the OBJECT mode such that we can ...
442     bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
443     # ... delete the new mesh including the separated vertex
444     bpy.ops.object.select_all(action='DESELECT')
445     new_object.select_set(True)
446     bpy.ops.object.delete()
447
448     # Create new atoms/vacancies at the position of the old atoms
449     # For all selected positions do:
450     for location in locations:
451         # Create a new object by duplication of the child of the dupliverts
452         # structure. <= this is done 'len(locations)' times. After each
453         # duplication, move the new object onto the positions
454         bpy.ops.object.select_all(action='DESELECT')
455         atom.children[0].select_set(True)
456         bpy.context.view_layer.objects.active = atom.children[0]
457         bpy.ops.object.duplicate_move()
458         new_atom = bpy.context.view_layer.objects.active
459         new_atom.parent = None
460         new_atom.location = location
461         new_atom.name = atom.name + "_sep"
462
463     bpy.context.view_layer.objects.active = atom
464
465
466 # Prepare a new material
467 def draw_obj_material(material_type, material):
468
469     if material_type == '0': # Unchanged
470         material_new = material
471     if material_type == '1': # Normal
472         material_new = bpy.data.materials.new(material.name + "_normal")
473     if material_type == '2': # Transparent
474         material_new = bpy.data.materials.new(material.name + "_transparent")
475         material_new.use_transparency = True
476         material_new.transparency_method = 'Z_TRANSPARENCY'
477         material_new.alpha = 1.3
478         material_new.raytrace_transparency.fresnel = 1.6
479         material_new.raytrace_transparency.fresnel_factor = 1.6
480     if material_type == '3': # Reflecting
481         material_new = bpy.data.materials.new(material.name + "_reflecting")
482         material_new.raytrace_mirror.use = True
483         material_new.raytrace_mirror.reflect_factor = 0.6
484         material_new.raytrace_mirror.fresnel = 0.0
485         material_new.raytrace_mirror.fresnel_factor = 1.250
486         material_new.raytrace_mirror.depth = 2
487         material_new.raytrace_mirror.distance = 0.0
488         material_new.raytrace_mirror.gloss_factor = 1.0
489     if material_type == '4': # Transparent + reflecting
490         material_new = bpy.data.materials.new(material.name + "_trans+refl")
491         material_new.use_transparency = True
492         material_new.transparency_method = 'Z_TRANSPARENCY'
493         material_new.alpha = 1.3
494         material_new.raytrace_transparency.fresnel = 1.6
495         material_new.raytrace_transparency.fresnel_factor = 1.6
496         material_new.raytrace_mirror.use = True
497         material_new.raytrace_mirror.reflect_factor = 0.6
498         material_new.raytrace_mirror.fresnel = 0.0
499         material_new.raytrace_mirror.fresnel_factor = 1.250
500         material_new.raytrace_mirror.depth = 2
501         material_new.raytrace_mirror.distance = 0.0
502         material_new.raytrace_mirror.gloss_factor = 1.0
503
504     # Always, when the material is changed, a new name is created. Note that
505     # this makes sense: Imagine, an other object uses the same material as the
506     # selected one. After changing the material of the selected object the old
507     # material should certainly not change and remain the same.
508     if material_type in {'1','2','3','4'}:
509         if "_repl" in material.name:
510             pos = material.name.rfind("_repl")
511             if material.name[pos+5:].isdigit():
512                 counter = int(material.name[pos+5:])
513                 material_new.name = material.name[:pos]+"_repl"+str(counter+1)
514             else:
515                 material_new.name = material.name+"_repl1"
516         else:
517             material_new.name = material.name+"_repl1"
518         material_new.diffuse_color = material.diffuse_color
519
520     return material_new
521
522
523 # Draw an object (e.g. cube, sphere, cylinder, ...)
524 def draw_obj(atom_shape, atom):
525
526     # No change
527     if atom_shape == '0':
528         return None
529
530     current_layers=bpy.context.scene.layers
531
532     if atom_shape == '1a': #Sphere mesh
533         bpy.ops.mesh.primitive_uv_sphere_add(
534             segments=32,
535             ring_count=32,
536             size=1,
537             view_align=False,
538             enter_editmode=False,
539             location=atom.location,
540             rotation=(0, 0, 0),
541             layers=current_layers)
542     if atom_shape == '1b': #Sphere NURBS
543         bpy.ops.surface.primitive_nurbs_surface_sphere_add(
544             view_align=False,
545             enter_editmode=False,
546             location=atom.location,
547             rotation=(0.0, 0.0, 0.0),
548             layers=current_layers)
549     if atom_shape == '2': #Cube
550         bpy.ops.mesh.primitive_cube_add(
551             view_align=False,
552             enter_editmode=False,
553             location=atom.location,
554             rotation=(0.0, 0.0, 0.0),
555             layers=current_layers)
556     if atom_shape == '3': #Plane
557         bpy.ops.mesh.primitive_plane_add(
558             view_align=False,
559             enter_editmode=False,
560             location=atom.location,
561             rotation=(0.0, 0.0, 0.0),
562             layers=current_layers)
563     if atom_shape == '4a': #Circle
564         bpy.ops.mesh.primitive_circle_add(
565             vertices=32,
566             radius=1,
567             fill_type='NOTHING',
568             view_align=False,
569             enter_editmode=False,
570             location=atom.location,
571             rotation=(0, 0, 0),
572             layers=current_layers)
573     if atom_shape == '4b': #Circle NURBS
574         bpy.ops.surface.primitive_nurbs_surface_circle_add(
575             view_align=False,
576             enter_editmode=False,
577             location=atom.location,
578             rotation=(0, 0, 0),
579             layers=current_layers)
580     if atom_shape in {'5a','5b','5c','5d','5e'}: #Icosphere
581         index = {'5a':1,'5b':2,'5c':3,'5d':4,'5e':5}
582         bpy.ops.mesh.primitive_ico_sphere_add(
583             subdivisions=int(index[atom_shape]),
584             size=1,
585             view_align=False,
586             enter_editmode=False,
587             location=atom.location,
588             rotation=(0, 0, 0),
589             layers=current_layers)
590     if atom_shape == '6a': #Cylinder
591         bpy.ops.mesh.primitive_cylinder_add(
592             vertices=32,
593             radius=1,
594             depth=2,
595             end_fill_type='NGON',
596             view_align=False,
597             enter_editmode=False,
598             location=atom.location,
599             rotation=(0, 0, 0),
600             layers=current_layers)
601     if atom_shape == '6b': #Cylinder NURBS
602         bpy.ops.surface.primitive_nurbs_surface_cylinder_add(
603             view_align=False,
604             enter_editmode=False,
605             location=atom.location,
606             rotation=(0, 0, 0),
607             layers=current_layers)
608     if atom_shape == '7': #Cone
609         bpy.ops.mesh.primitive_cone_add(
610             vertices=32,
611             radius1=1,
612             radius2=0,
613             depth=2,
614             end_fill_type='NGON',
615             view_align=False,
616             enter_editmode=False,
617             location=atom.location,
618             rotation=(0, 0, 0),
619             layers=current_layers)
620     if atom_shape == '8a': #Torus
621         bpy.ops.mesh.primitive_torus_add(
622             rotation=(0, 0, 0),
623             location=atom.location,
624             view_align=False,
625             major_radius=1,
626             minor_radius=0.25,
627             major_segments=48,
628             minor_segments=12,
629             abso_major_rad=1,
630             abso_minor_rad=0.5)
631     if atom_shape == '8b': #Torus NURBS
632         bpy.ops.surface.primitive_nurbs_surface_torus_add(
633             view_align=False,
634             enter_editmode=False,
635             location=atom.location,
636             rotation=(0, 0, 0),
637             layers=current_layers)
638
639     new_atom = bpy.context.view_layer.objects.active
640     new_atom.scale = atom.scale + Vector((0.0,0.0,0.0))
641     new_atom.name = atom.name + "_tmp"
642     new_atom.select_set(True)
643
644     return new_atom
645
646
647 # Draw a special object (e.g. halo, etc. ...)
648 def draw_obj_special(atom_shape, atom):
649
650     current_layers=bpy.context.scene.layers
651
652     # Halo cloud
653     if atom_shape == '1':
654         # Build one mesh point
655         new_mesh = bpy.data.meshes.new("Mesh_"+atom.name)
656         new_mesh.from_pydata([Vector((0.0,0.0,0.0))], [], [])
657         new_mesh.update()
658         new_atom = bpy.data.objects.new(atom.name + "_sep", new_mesh)
659         bpy.context.collection.objects.link(new_atom)
660         new_atom.location = atom.location
661         material_new = bpy.data.materials.new(atom.active_material.name + "_sep")
662         material_new.name = atom.name + "_halo"
663         material_new.diffuse_color = atom.active_material.diffuse_color
664         material_new.type = 'HALO'
665         material_new.halo.size = atom.scale[0]*1.5
666         material_new.halo.hardness = 25
667         material_new.halo.add = 0.0
668         new_atom.active_material = material_new
669         new_atom.name = atom.name
670         new_atom.select_set(True)
671     # F2+ center
672     if atom_shape == '2':
673         # Create first a cube
674         bpy.ops.mesh.primitive_cube_add(view_align=False,
675                                         enter_editmode=False,
676                                         location=atom.location,
677                                         rotation=(0.0, 0.0, 0.0),
678                                         layers=current_layers)
679         cube = bpy.context.view_layer.objects.active
680         cube.scale = atom.scale + Vector((0.0,0.0,0.0))
681         cube.name = atom.name + "_F2+-center"
682         cube.select_set(True)
683         # New material for this cube
684         material_cube = bpy.data.materials.new(atom.name + "_F2+-center")
685         material_cube.diffuse_color = [0.8,0.0,0.0]
686         material_cube.use_transparency = True
687         material_cube.transparency_method = 'Z_TRANSPARENCY'
688         material_cube.alpha = 1.0
689         material_cube.raytrace_transparency.fresnel = 1.6
690         material_cube.raytrace_transparency.fresnel_factor = 1.1
691         cube.active_material = material_cube
692         # Put a nice point lamp inside the defect
693         lamp_data = bpy.data.lamps.new(name="F2+_lamp", type="POINT")
694         lamp_data.distance = atom.scale[0] * 2.0
695         lamp_data.energy = 20.0
696         lamp_data.use_sphere = True
697         lamp_data.color = [0.8,0.8,0.8]
698         lamp = bpy.data.objects.new("F2+_lamp", lamp_data)
699         lamp.location = Vector((0.0, 0.0, 0.0))
700         lamp.layers = current_layers
701         bpy.context.collection.objects.link(lamp)
702         lamp.parent = cube
703         # The new 'atom' is the F2+ defect
704         new_atom = cube
705     # F+ center
706     if atom_shape == '3':
707         # Create first a cube
708         bpy.ops.mesh.primitive_cube_add(view_align=False,
709                                         enter_editmode=False,
710                                         location=atom.location,
711                                         rotation=(0.0, 0.0, 0.0),
712                                         layers=current_layers)
713         cube = bpy.context.view_layer.objects.active
714         cube.scale = atom.scale + Vector((0.0,0.0,0.0))
715         cube.name = atom.name + "_F+-center"
716         cube.select_set(True)
717         # New material for this cube
718         material_cube = bpy.data.materials.new(atom.name + "_F+-center")
719         material_cube.diffuse_color = [0.8,0.8,0.0]
720         material_cube.use_transparency = True
721         material_cube.transparency_method = 'Z_TRANSPARENCY'
722         material_cube.alpha = 1.0
723         material_cube.raytrace_transparency.fresnel = 1.6
724         material_cube.raytrace_transparency.fresnel_factor = 1.1
725         cube.active_material = material_cube
726         # Create now an electron
727         scale = atom.scale / 10.0
728         bpy.ops.surface.primitive_nurbs_surface_sphere_add(
729                                         view_align=False,
730                                         enter_editmode=False,
731                                         location=(0.0, 0.0, 0.0),
732                                         rotation=(0.0, 0.0, 0.0),
733                                         layers=current_layers)
734         electron = bpy.context.view_layer.objects.active
735         electron.scale = scale
736         electron.name = atom.name + "_F+_electron"
737         electron.parent = cube
738         # New material for the electron
739         material_electron = bpy.data.materials.new(atom.name + "_F+-center")
740         material_electron.diffuse_color = [0.0,0.0,0.8]
741         material_electron.specular_hardness = 200
742         material_electron.emit = 1.0
743         material_electron.use_transparency = True
744         material_electron.transparency_method = 'Z_TRANSPARENCY'
745         material_electron.alpha = 1.3
746         material_electron.raytrace_transparency.fresnel = 1.2
747         material_electron.raytrace_transparency.fresnel_factor = 1.2
748         electron.active_material = material_electron
749         # Put a nice point lamp inside the electron
750         lamp_data = bpy.data.lamps.new(name="F+_lamp", type="POINT")
751         lamp_data.distance = atom.scale[0] * 2.0
752         lamp_data.energy = 20.0
753         lamp_data.use_sphere = True
754         lamp_data.color = [0.8,0.8,0.8]
755         lamp = bpy.data.objects.new("F+_lamp", lamp_data)
756         lamp.location = Vector((0.0, 0.0, 0.0))
757         lamp.layers = current_layers
758         bpy.context.collection.objects.link(lamp)
759         lamp.parent = cube
760         # The new 'atom' is the F+ defect complex + lamp
761         new_atom = cube
762     # F0 center
763     if atom_shape == '4':
764         # Create first a cube
765         bpy.ops.mesh.primitive_cube_add(view_align=False,
766                                         enter_editmode=False,
767                                         location=atom.location,
768                                         rotation=(0.0, 0.0, 0.0),
769                                         layers=current_layers)
770         cube = bpy.context.view_layer.objects.active
771         cube.scale = atom.scale + Vector((0.0,0.0,0.0))
772         cube.name = atom.name + "_F0-center"
773         cube.select_set(True)
774         # New material for this cube
775         material_cube = bpy.data.materials.new(atom.name + "_F0-center")
776         material_cube.diffuse_color = [0.8,0.8,0.8]
777         material_cube.use_transparency = True
778         material_cube.transparency_method = 'Z_TRANSPARENCY'
779         material_cube.alpha = 1.0
780         material_cube.raytrace_transparency.fresnel = 1.6
781         material_cube.raytrace_transparency.fresnel_factor = 1.1
782         cube.active_material = material_cube
783         # Create now two electrons
784         scale = atom.scale / 10.0
785         bpy.ops.surface.primitive_nurbs_surface_sphere_add(
786                                         view_align=False,
787                                         enter_editmode=False,
788                                         location=(scale[0]*1.5,0.0,0.0),
789                                         rotation=(0.0, 0.0, 0.0),
790                                         layers=current_layers)
791         electron1 = bpy.context.view_layer.objects.active
792         electron1.scale = scale
793         electron1.name = atom.name + "_F0_electron1"
794         electron1.parent = cube
795         bpy.ops.surface.primitive_nurbs_surface_sphere_add(
796                                         view_align=False,
797                                         enter_editmode=False,
798                                         location=(-scale[0]*1.5,0.0,0.0),
799                                         rotation=(0.0, 0.0, 0.0),
800                                         layers=current_layers)
801         electron2 = bpy.context.view_layer.objects.active
802         electron2.scale = scale
803         electron2.name = atom.name + "_F0_electron2"
804         electron2.parent = cube
805         # New material for the electrons
806         material_electron = bpy.data.materials.new(atom.name + "_F0-center")
807         material_electron.diffuse_color = [0.0,0.0,0.8]
808         material_electron.specular_hardness = 200
809         material_electron.emit = 1.0
810         material_electron.use_transparency = True
811         material_electron.transparency_method = 'Z_TRANSPARENCY'
812         material_electron.alpha = 1.3
813         material_electron.raytrace_transparency.fresnel = 1.2
814         material_electron.raytrace_transparency.fresnel_factor = 1.2
815         electron1.active_material = material_electron
816         electron2.active_material = material_electron
817         # Put two nice point lamps inside the electrons
818         lamp1_data = bpy.data.lamps.new(name="F0_lamp1", type="POINT")
819         lamp1_data.distance = atom.scale[0] * 2.0
820         lamp1_data.energy = 8.0
821         lamp1_data.use_sphere = True
822         lamp1_data.color = [0.8,0.8,0.8]
823         lamp1 = bpy.data.objects.new("F0_lamp", lamp1_data)
824         lamp1.location = Vector((scale[0]*1.5, 0.0, 0.0))
825         lamp1.layers = current_layers
826         bpy.context.collection.objects.link(lamp1)
827         lamp1.parent = cube
828         lamp2_data = bpy.data.lamps.new(name="F0_lamp2", type="POINT")
829         lamp2_data.distance = atom.scale[0] * 2.0
830         lamp2_data.energy = 8.0
831         lamp2_data.use_sphere = True
832         lamp2_data.color = [0.8,0.8,0.8]
833         lamp2 = bpy.data.objects.new("F0_lamp", lamp2_data)
834         lamp2.location = Vector((-scale[0]*1.5, 0.0, 0.0))
835         lamp2.layers = current_layers
836         bpy.context.collection.objects.link(lamp2)
837         lamp2.parent = cube
838         # The new 'atom' is the F0 defect complex + lamps
839         new_atom = cube
840
841     return new_atom
842
843
844 # Initialization of the list 'ELEMENTS'.
845 def read_elements():
846
847     del ELEMENTS[:]
848
849     for item in ELEMENTS_DEFAULT:
850
851         # All three radii into a list
852         radii = [item[4],item[5],item[6]]
853         # The handling of the ionic radii will be done later. So far, it is an
854         # empty list.
855         radii_ionic = item[7:]
856
857         li = ElementProp(item[0],item[1],item[2],item[3],
858                                      radii,radii_ionic)
859         ELEMENTS.append(li)
860
861
862 # Custom data file: changing color and radii by using the list 'ELEMENTS'.
863 def custom_datafile_change_atom_props():
864
865     for atom in bpy.context.selected_objects:
866         if len(atom.children) != 0:
867             child = atom.children[0]
868             if child.type in {'SURFACE', 'MESH', 'META'}:
869                 for element in ELEMENTS:
870                     if element.name in atom.name:
871                         child.scale = (element.radii[0],) * 3
872                         child.active_material.diffuse_color = element.color
873         else:
874             if atom.type in {'SURFACE', 'MESH', 'META'}:
875                 for element in ELEMENTS:
876                     if element.name in atom.name:
877                         atom.scale = (element.radii[0],) * 3
878                         atom.active_material.diffuse_color = element.color
879
880
881 # Reading a custom data file and modifying the list 'ELEMENTS'.
882 def custom_datafile(path_datafile):
883
884     if path_datafile == "":
885         return False
886
887     path_datafile = bpy.path.abspath(path_datafile)
888
889     if os.path.isfile(path_datafile) == False:
890         return False
891
892     # The whole list gets deleted! We build it new.
893     del ELEMENTS[:]
894
895     # Read the data file, which contains all data
896     # (atom name, radii, colors, etc.)
897     data_file_p = open(path_datafile, "r")
898
899     for line in data_file_p:
900
901         if "Atom" in line:
902
903             line = data_file_p.readline()
904             # Number
905             line = data_file_p.readline()
906             number = line[19:-1]
907             # Name
908             line = data_file_p.readline()
909             name = line[19:-1]
910             # Short name
911             line = data_file_p.readline()
912             short_name = line[19:-1]
913             # Color
914             line = data_file_p.readline()
915             color_value = line[19:-1].split(',')
916             color = [float(color_value[0]),
917                      float(color_value[1]),
918                      float(color_value[2])]
919             # Used radius
920             line = data_file_p.readline()
921             radius_used = float(line[19:-1])
922             # Atomic radius
923             line = data_file_p.readline()
924             radius_atomic = float(line[19:-1])
925             # Van der Waals radius
926             line = data_file_p.readline()
927             radius_vdW = float(line[19:-1])
928             radii = [radius_used,radius_atomic,radius_vdW]
929             radii_ionic = []
930
931             element = ElementProp(number,name,short_name,color,
932                                               radii, radii_ionic)
933
934             ELEMENTS.append(element)
935
936     data_file_p.close()
937
938     return True