Cleanup: quiet float argument to in type warning
[blender-addons.git] / io_mesh_atomic / utility_panel.py
blobdcab8df93a83bc5186206e6fc83b7eee0a64024e
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 import os
4 import bpy
5 import bmesh
6 from mathutils import Vector
7 from math import sqrt
8 from copy import copy
10 # -----------------------------------------------------------------------------
11 # Atom and element data
14 # This is a list that contains some data of all possible elements. The structure
15 # is as follows:
17 # 1, "Hydrogen", "H", [0.0,0.0,1.0], 0.32, 0.32, 0.32 , -1 , 1.54 means
19 # No., name, short name, color, radius (used), radius (covalent), radius (atomic),
21 # charge state 1, radius (ionic) 1, charge state 2, radius (ionic) 2, ... all
22 # charge states for any atom are listed, if existing.
23 # The list is fixed and cannot be changed ... (see below)
25 ELEMENTS_DEFAULT = (
26 ( 1, "Hydrogen", "H", ( 1.0, 1.0, 1.0, 1.0), 0.32, 0.32, 0.79 , -1 , 1.54 ),
27 ( 2, "Helium", "He", ( 0.85, 1.0, 1.0, 1.0), 0.93, 0.93, 0.49 ),
28 ( 3, "Lithium", "Li", ( 0.8, 0.50, 1.0, 1.0), 1.23, 1.23, 2.05 , 1 , 0.68 ),
29 ( 4, "Beryllium", "Be", ( 0.76, 1.0, 0.0, 1.0), 0.90, 0.90, 1.40 , 1 , 0.44 , 2 , 0.35 ),
30 ( 5, "Boron", "B", ( 1.0, 0.70, 0.70, 1.0), 0.82, 0.82, 1.17 , 1 , 0.35 , 3 , 0.23 ),
31 ( 6, "Carbon", "C", ( 0.56, 0.56, 0.56, 1.0), 0.77, 0.77, 0.91 , -4 , 2.60 , 4 , 0.16 ),
32 ( 7, "Nitrogen", "N", ( 0.18, 0.31, 0.97, 1.0), 0.75, 0.75, 0.75 , -3 , 1.71 , 1 , 0.25 , 3 , 0.16 , 5 , 0.13 ),
33 ( 8, "Oxygen", "O", ( 1.0, 0.05, 0.05, 1.0), 0.73, 0.73, 0.65 , -2 , 1.32 , -1 , 1.76 , 1 , 0.22 , 6 , 0.09 ),
34 ( 9, "Fluorine", "F", ( 0.56, 0.87, 0.31, 1.0), 0.72, 0.72, 0.57 , -1 , 1.33 , 7 , 0.08 ),
35 (10, "Neon", "Ne", ( 0.70, 0.89, 0.96, 1.0), 0.71, 0.71, 0.51 , 1 , 1.12 ),
36 (11, "Sodium", "Na", ( 0.67, 0.36, 0.94, 1.0), 1.54, 1.54, 2.23 , 1 , 0.97 ),
37 (12, "Magnesium", "Mg", ( 0.54, 1.0, 0.0, 1.0), 1.36, 1.36, 1.72 , 1 , 0.82 , 2 , 0.66 ),
38 (13, "Aluminium", "Al", ( 0.74, 0.65, 0.65, 1.0), 1.18, 1.18, 1.82 , 3 , 0.51 ),
39 (14, "Silicon", "Si", ( 0.94, 0.78, 0.62, 1.0), 1.11, 1.11, 1.46 , -4 , 2.71 , -1 , 3.84 , 1 , 0.65 , 4 , 0.42 ),
40 (15, "Phosphorus", "P", ( 1.0, 0.50, 0.0, 1.0), 1.06, 1.06, 1.23 , -3 , 2.12 , 3 , 0.44 , 5 , 0.35 ),
41 (16, "Sulfur", "S", ( 1.0, 1.0, 0.18, 1.0), 1.02, 1.02, 1.09 , -2 , 1.84 , 2 , 2.19 , 4 , 0.37 , 6 , 0.30 ),
42 (17, "Chlorine", "Cl", ( 0.12, 0.94, 0.12, 1.0), 0.99, 0.99, 0.97 , -1 , 1.81 , 5 , 0.34 , 7 , 0.27 ),
43 (18, "Argon", "Ar", ( 0.50, 0.81, 0.89, 1.0), 0.98, 0.98, 0.88 , 1 , 1.54 ),
44 (19, "Potassium", "K", ( 0.56, 0.25, 0.83, 1.0), 2.03, 2.03, 2.77 , 1 , 0.81 ),
45 (20, "Calcium", "Ca", ( 0.23, 1.0, 0.0, 1.0), 1.74, 1.74, 2.23 , 1 , 1.18 , 2 , 0.99 ),
46 (21, "Scandium", "Sc", ( 0.90, 0.90, 0.90, 1.0), 1.44, 1.44, 2.09 , 3 , 0.73 ),
47 (22, "Titanium", "Ti", ( 0.74, 0.76, 0.78, 1.0), 1.32, 1.32, 2.00 , 1 , 0.96 , 2 , 0.94 , 3 , 0.76 , 4 , 0.68 ),
48 (23, "Vanadium", "V", ( 0.65, 0.65, 0.67, 1.0), 1.22, 1.22, 1.92 , 2 , 0.88 , 3 , 0.74 , 4 , 0.63 , 5 , 0.59 ),
49 (24, "Chromium", "Cr", ( 0.54, 0.6, 0.78, 1.0), 1.18, 1.18, 1.85 , 1 , 0.81 , 2 , 0.89 , 3 , 0.63 , 6 , 0.52 ),
50 (25, "Manganese", "Mn", ( 0.61, 0.47, 0.78, 1.0), 1.17, 1.17, 1.79 , 2 , 0.80 , 3 , 0.66 , 4 , 0.60 , 7 , 0.46 ),
51 (26, "Iron", "Fe", ( 0.87, 0.4, 0.2, 1.0), 1.17, 1.17, 1.72 , 2 , 0.74 , 3 , 0.64 ),
52 (27, "Cobalt", "Co", ( 0.94, 0.56, 0.62, 1.0), 1.16, 1.16, 1.67 , 2 , 0.72 , 3 , 0.63 ),
53 (28, "Nickel", "Ni", ( 0.31, 0.81, 0.31, 1.0), 1.15, 1.15, 1.62 , 2 , 0.69 ),
54 (29, "Copper", "Cu", ( 0.78, 0.50, 0.2, 1.0), 1.17, 1.17, 1.57 , 1 , 0.96 , 2 , 0.72 ),
55 (30, "Zinc", "Zn", ( 0.49, 0.50, 0.69, 1.0), 1.25, 1.25, 1.53 , 1 , 0.88 , 2 , 0.74 ),
56 (31, "Gallium", "Ga", ( 0.76, 0.56, 0.56, 1.0), 1.26, 1.26, 1.81 , 1 , 0.81 , 3 , 0.62 ),
57 (32, "Germanium", "Ge", ( 0.4, 0.56, 0.56, 1.0), 1.22, 1.22, 1.52 , -4 , 2.72 , 2 , 0.73 , 4 , 0.53 ),
58 (33, "Arsenic", "As", ( 0.74, 0.50, 0.89, 1.0), 1.20, 1.20, 1.33 , -3 , 2.22 , 3 , 0.58 , 5 , 0.46 ),
59 (34, "Selenium", "Se", ( 1.0, 0.63, 0.0, 1.0), 1.16, 1.16, 1.22 , -2 , 1.91 , -1 , 2.32 , 1 , 0.66 , 4 , 0.50 , 6 , 0.42 ),
60 (35, "Bromine", "Br", ( 0.65, 0.16, 0.16, 1.0), 1.14, 1.14, 1.12 , -1 , 1.96 , 5 , 0.47 , 7 , 0.39 ),
61 (36, "Krypton", "Kr", ( 0.36, 0.72, 0.81, 1.0), 1.31, 1.31, 1.24 ),
62 (37, "Rubidium", "Rb", ( 0.43, 0.18, 0.69, 1.0), 2.16, 2.16, 2.98 , 1 , 1.47 ),
63 (38, "Strontium", "Sr", ( 0.0, 1.0, 0.0, 1.0), 1.91, 1.91, 2.45 , 2 , 1.12 ),
64 (39, "Yttrium", "Y", ( 0.58, 1.0, 1.0, 1.0), 1.62, 1.62, 2.27 , 3 , 0.89 ),
65 (40, "Zirconium", "Zr", ( 0.58, 0.87, 0.87, 1.0), 1.45, 1.45, 2.16 , 1 , 1.09 , 4 , 0.79 ),
66 (41, "Niobium", "Nb", ( 0.45, 0.76, 0.78, 1.0), 1.34, 1.34, 2.08 , 1 , 1.00 , 4 , 0.74 , 5 , 0.69 ),
67 (42, "Molybdenum", "Mo", ( 0.32, 0.70, 0.70, 1.0), 1.30, 1.30, 2.01 , 1 , 0.93 , 4 , 0.70 , 6 , 0.62 ),
68 (43, "Technetium", "Tc", ( 0.23, 0.61, 0.61, 1.0), 1.27, 1.27, 1.95 , 7 , 0.97 ),
69 (44, "Ruthenium", "Ru", ( 0.14, 0.56, 0.56, 1.0), 1.25, 1.25, 1.89 , 4 , 0.67 ),
70 (45, "Rhodium", "Rh", ( 0.03, 0.49, 0.54, 1.0), 1.25, 1.25, 1.83 , 3 , 0.68 ),
71 (46, "Palladium", "Pd", ( 0.0, 0.41, 0.52, 1.0), 1.28, 1.28, 1.79 , 2 , 0.80 , 4 , 0.65 ),
72 (47, "Silver", "Ag", ( 0.75, 0.75, 0.75, 1.0), 1.34, 1.34, 1.75 , 1 , 1.26 , 2 , 0.89 ),
73 (48, "Cadmium", "Cd", ( 1.0, 0.85, 0.56, 1.0), 1.48, 1.48, 1.71 , 1 , 1.14 , 2 , 0.97 ),
74 (49, "Indium", "In", ( 0.65, 0.45, 0.45, 1.0), 1.44, 1.44, 2.00 , 3 , 0.81 ),
75 (50, "Tin", "Sn", ( 0.4, 0.50, 0.50, 1.0), 1.41, 1.41, 1.72 , -4 , 2.94 , -1 , 3.70 , 2 , 0.93 , 4 , 0.71 ),
76 (51, "Antimony", "Sb", ( 0.61, 0.38, 0.70, 1.0), 1.40, 1.40, 1.53 , -3 , 2.45 , 3 , 0.76 , 5 , 0.62 ),
77 (52, "Tellurium", "Te", ( 0.83, 0.47, 0.0, 1.0), 1.36, 1.36, 1.42 , -2 , 2.11 , -1 , 2.50 , 1 , 0.82 , 4 , 0.70 , 6 , 0.56 ),
78 (53, "Iodine", "I", ( 0.58, 0.0, 0.58, 1.0), 1.33, 1.33, 1.32 , -1 , 2.20 , 5 , 0.62 , 7 , 0.50 ),
79 (54, "Xenon", "Xe", ( 0.25, 0.61, 0.69, 1.0), 1.31, 1.31, 1.24 ),
80 (55, "Caesium", "Cs", ( 0.34, 0.09, 0.56, 1.0), 2.35, 2.35, 3.35 , 1 , 1.67 ),
81 (56, "Barium", "Ba", ( 0.0, 0.78, 0.0, 1.0), 1.98, 1.98, 2.78 , 1 , 1.53 , 2 , 1.34 ),
82 (57, "Lanthanum", "La", ( 0.43, 0.83, 1.0, 1.0), 1.69, 1.69, 2.74 , 1 , 1.39 , 3 , 1.06 ),
83 (58, "Cerium", "Ce", ( 1.0, 1.0, 0.78, 1.0), 1.65, 1.65, 2.70 , 1 , 1.27 , 3 , 1.03 , 4 , 0.92 ),
84 (59, "Praseodymium", "Pr", ( 0.85, 1.0, 0.78, 1.0), 1.65, 1.65, 2.67 , 3 , 1.01 , 4 , 0.90 ),
85 (60, "Neodymium", "Nd", ( 0.78, 1.0, 0.78, 1.0), 1.64, 1.64, 2.64 , 3 , 0.99 ),
86 (61, "Promethium", "Pm", ( 0.63, 1.0, 0.78, 1.0), 1.63, 1.63, 2.62 , 3 , 0.97 ),
87 (62, "Samarium", "Sm", ( 0.56, 1.0, 0.78, 1.0), 1.62, 1.62, 2.59 , 3 , 0.96 ),
88 (63, "Europium", "Eu", ( 0.38, 1.0, 0.78, 1.0), 1.85, 1.85, 2.56 , 2 , 1.09 , 3 , 0.95 ),
89 (64, "Gadolinium", "Gd", ( 0.27, 1.0, 0.78, 1.0), 1.61, 1.61, 2.54 , 3 , 0.93 ),
90 (65, "Terbium", "Tb", ( 0.18, 1.0, 0.78, 1.0), 1.59, 1.59, 2.51 , 3 , 0.92 , 4 , 0.84 ),
91 (66, "Dysprosium", "Dy", ( 0.12, 1.0, 0.78, 1.0), 1.59, 1.59, 2.49 , 3 , 0.90 ),
92 (67, "Holmium", "Ho", ( 0.0, 1.0, 0.61, 1.0), 1.58, 1.58, 2.47 , 3 , 0.89 ),
93 (68, "Erbium", "Er", ( 0.0, 0.90, 0.45, 1.0), 1.57, 1.57, 2.45 , 3 , 0.88 ),
94 (69, "Thulium", "Tm", ( 0.0, 0.83, 0.32, 1.0), 1.56, 1.56, 2.42 , 3 , 0.87 ),
95 (70, "Ytterbium", "Yb", ( 0.0, 0.74, 0.21, 1.0), 1.74, 1.74, 2.40 , 2 , 0.93 , 3 , 0.85 ),
96 (71, "Lutetium", "Lu", ( 0.0, 0.67, 0.14, 1.0), 1.56, 1.56, 2.25 , 3 , 0.85 ),
97 (72, "Hafnium", "Hf", ( 0.30, 0.76, 1.0, 1.0), 1.44, 1.44, 2.16 , 4 , 0.78 ),
98 (73, "Tantalum", "Ta", ( 0.30, 0.65, 1.0, 1.0), 1.34, 1.34, 2.09 , 5 , 0.68 ),
99 (74, "Tungsten", "W", ( 0.12, 0.58, 0.83, 1.0), 1.30, 1.30, 2.02 , 4 , 0.70 , 6 , 0.62 ),
100 (75, "Rhenium", "Re", ( 0.14, 0.49, 0.67, 1.0), 1.28, 1.28, 1.97 , 4 , 0.72 , 7 , 0.56 ),
101 (76, "Osmium", "Os", ( 0.14, 0.4, 0.58, 1.0), 1.26, 1.26, 1.92 , 4 , 0.88 , 6 , 0.69 ),
102 (77, "Iridium", "Ir", ( 0.09, 0.32, 0.52, 1.0), 1.27, 1.27, 1.87 , 4 , 0.68 ),
103 (78, "Platinum", "Pt", ( 0.81, 0.81, 0.87, 1.0), 1.30, 1.30, 1.83 , 2 , 0.80 , 4 , 0.65 ),
104 (79, "Gold", "Au", ( 1.0, 0.81, 0.13, 1.0), 1.34, 1.34, 1.79 , 1 , 1.37 , 3 , 0.85 ),
105 (80, "Mercury", "Hg", ( 0.72, 0.72, 0.81, 1.0), 1.49, 1.49, 1.76 , 1 , 1.27 , 2 , 1.10 ),
106 (81, "Thallium", "Tl", ( 0.65, 0.32, 0.30, 1.0), 1.48, 1.48, 2.08 , 1 , 1.47 , 3 , 0.95 ),
107 (82, "Lead", "Pb", ( 0.34, 0.34, 0.38, 1.0), 1.47, 1.47, 1.81 , 2 , 1.20 , 4 , 0.84 ),
108 (83, "Bismuth", "Bi", ( 0.61, 0.30, 0.70, 1.0), 1.46, 1.46, 1.63 , 1 , 0.98 , 3 , 0.96 , 5 , 0.74 ),
109 (84, "Polonium", "Po", ( 0.67, 0.36, 0.0, 1.0), 1.46, 1.46, 1.53 , 6 , 0.67 ),
110 (85, "Astatine", "At", ( 0.45, 0.30, 0.27, 1.0), 1.45, 1.45, 1.43 , -3 , 2.22 , 3 , 0.85 , 5 , 0.46 ),
111 (86, "Radon", "Rn", ( 0.25, 0.50, 0.58, 1.0), 1.00, 1.00, 1.34 ),
112 (87, "Francium", "Fr", ( 0.25, 0.0, 0.4, 1.0), 1.00, 1.00, 1.00 , 1 , 1.80 ),
113 (88, "Radium", "Ra", ( 0.0, 0.49, 0.0, 1.0), 1.00, 1.00, 1.00 , 2 , 1.43 ),
114 (89, "Actinium", "Ac", ( 0.43, 0.67, 0.98, 1.0), 1.00, 1.00, 1.00 , 3 , 1.18 ),
115 (90, "Thorium", "Th", ( 0.0, 0.72, 1.0, 1.0), 1.65, 1.65, 1.00 , 4 , 1.02 ),
116 (91, "Protactinium", "Pa", ( 0.0, 0.63, 1.0, 1.0), 1.00, 1.00, 1.00 , 3 , 1.13 , 4 , 0.98 , 5 , 0.89 ),
117 (92, "Uranium", "U", ( 0.0, 0.56, 1.0, 1.0), 1.42, 1.42, 1.00 , 4 , 0.97 , 6 , 0.80 ),
118 (93, "Neptunium", "Np", ( 0.0, 0.50, 1.0, 1.0), 1.00, 1.00, 1.00 , 3 , 1.10 , 4 , 0.95 , 7 , 0.71 ),
119 (94, "Plutonium", "Pu", ( 0.0, 0.41, 1.0, 1.0), 1.00, 1.00, 1.00 , 3 , 1.08 , 4 , 0.93 ),
120 (95, "Americium", "Am", ( 0.32, 0.36, 0.94, 1.0), 1.00, 1.00, 1.00 , 3 , 1.07 , 4 , 0.92 ),
121 (96, "Curium", "Cm", ( 0.47, 0.36, 0.89, 1.0), 1.00, 1.00, 1.00 ),
122 (97, "Berkelium", "Bk", ( 0.54, 0.30, 0.89, 1.0), 1.00, 1.00, 1.00 ),
123 (98, "Californium", "Cf", ( 0.63, 0.21, 0.83, 1.0), 1.00, 1.00, 1.00 ),
124 (99, "Einsteinium", "Es", ( 0.70, 0.12, 0.83, 1.0), 1.00, 1.00, 1.00 ),
125 (100, "Fermium", "Fm", ( 0.70, 0.12, 0.72, 1.0), 1.00, 1.00, 1.00 ),
126 (101, "Mendelevium", "Md", ( 0.70, 0.05, 0.65, 1.0), 1.00, 1.00, 1.00 ),
127 (102, "Nobelium", "No", ( 0.74, 0.05, 0.52, 1.0), 1.00, 1.00, 1.00 ),
128 (103, "Lawrencium", "Lr", ( 0.78, 0.0, 0.4, 1.0), 1.00, 1.00, 1.00 ),
129 (104, "Vacancy", "Vac", ( 0.5, 0.5, 0.5, 1.0), 1.00, 1.00, 1.00),
130 (105, "Default", "Default", ( 1.0, 1.0, 1.0, 1.0), 1.00, 1.00, 1.00),
131 (106, "Stick", "Stick", ( 0.5, 0.5, 0.5, 1.0), 1.00, 1.00, 1.00),
134 # The list 'ELEMENTS' contains all data of the elements and will be used during
135 # runtime. The list will be initialized with the fixed
136 # data from above via the class below (ElementProp). One fixed list (above),
137 # which cannot be changed, and a list of classes with same data (ELEMENTS) exist.
138 # The list 'ELEMENTS' can be modified by e.g. loading a separate custom
139 # data file.
140 ELEMENTS = []
143 # This is the class, which stores the properties for one element.
144 class ElementProp(object):
145 __slots__ = ('number',
146 'name',
147 'short_name',
148 'color',
149 'radii',
150 'radii_ionic',
151 'mat_P_BSDF',
152 'mat_Eevee')
153 def __init__(self,
154 number,
155 name,
156 short_name,
157 color,
158 radii,
159 radii_ionic,
160 mat_P_BSDF,
161 mat_Eevee):
162 self.number = number
163 self.name = name
164 self.short_name = short_name
165 self.color = color
166 self.radii = radii
167 self.radii_ionic = radii_ionic
168 self.mat_P_BSDF = mat_P_BSDF
169 self.mat_Eevee = mat_Eevee
172 class PBSDFProp(object):
173 __slots__ = ('Subsurface_method',
174 'Distribution',
175 'Subsurface',
176 'Subsurface_color',
177 'Subsurface_radius',
178 'Metallic',
179 'Specular',
180 'Specular_tilt',
181 'Roughness',
182 'Anisotropic',
183 'Anisotropic_rotation',
184 'Sheen',
185 'Sheen_tint',
186 'Clearcoat',
187 'Clearcoat_rough',
188 'IOR',
189 'Trans',
190 'Trans_rough',
191 'Emission',
192 'Emission_strength',
193 'Alpha')
194 def __init__(self,
195 Subsurface_method,
196 Distribution,
197 Subsurface,
198 Subsurface_color,
199 Subsurface_radius,
200 Metallic,
201 Specular,
202 Specular_tilt,
203 Roughness,
204 Anisotropic,
205 Anisotropic_rotation,
206 Sheen,
207 Sheen_tint,
208 Clearcoat,
209 Clearcoat_rough,
210 IOR,
211 Trans,
212 Trans_rough,
213 Emission,
214 Emission_strength,
215 Alpha):
216 self.Subsurface_method = Subsurface_method
217 self.Distribution = Distribution
218 self.Subsurface = Subsurface
219 self.Subsurface_color = Subsurface_color
220 self.Subsurface_radius = Subsurface_radius
221 self.Metallic = Metallic
222 self.Specular = Specular
223 self.Specular_tilt = Specular_tilt
224 self.Roughness = Roughness
225 self.Anisotropic = Anisotropic
226 self.Anisotropic_rotation = Anisotropic_rotation
227 self.Sheen = Sheen
228 self.Sheen_tint = Sheen_tint
229 self.Clearcoat = Clearcoat
230 self.Clearcoat_rough = Clearcoat_rough
231 self.IOR = IOR
232 self.Trans = Trans
233 self.Trans_rough = Trans_rough
234 self.Emission = Emission
235 self.Emission_strength = Emission_strength
236 self.Alpha = Alpha
239 class EeveeProp(object):
240 __slots__ = ('use_backface',
241 'blend_method',
242 'shadow_method',
243 'clip_threshold',
244 'use_screen_refraction',
245 'refraction_depth',
246 'use_sss_translucency',
247 'pass_index')
248 def __init__(self,
249 use_backface,
250 blend_method,
251 shadow_method,
252 clip_threshold,
253 use_screen_refraction,
254 refraction_depth,
255 use_sss_translucency,
256 pass_index):
257 self.use_backface = use_backface
258 self.blend_method = blend_method
259 self.shadow_method = shadow_method
260 self.clip_threshold = clip_threshold
261 self.use_screen_refraction = use_screen_refraction
262 self.refraction_depth = refraction_depth
263 self.use_sss_translucency = use_sss_translucency
264 self.pass_index = pass_index
267 # This function measures the distance between two selected objects.
268 def distance():
270 # In the 'EDIT' mode
271 if bpy.context.mode == 'EDIT_MESH':
273 atom = bpy.context.edit_object
274 bm = bmesh.from_edit_mesh(atom.data)
275 locations = []
277 for v in bm.verts:
278 if v.select:
279 locations.append(atom.matrix_world @ v.co)
281 if len(locations) > 1:
282 location1 = locations[0]
283 location2 = locations[1]
284 else:
285 return "N.A"
286 # In the 'OBJECT' mode
287 else:
289 if len(bpy.context.selected_objects) > 1:
290 location1 = bpy.context.selected_objects[0].location
291 location2 = bpy.context.selected_objects[1].location
292 else:
293 return "N.A."
295 dv = location2 - location1
296 dist = str(dv.length)
297 pos = str.find(dist, ".")
298 dist = dist[:pos+4]
299 dist = dist + " A"
301 return dist
304 def choose_objects(action_type,
305 radius_all,
306 radius_pm,
307 radius_type,
308 radius_type_ionic,
309 sticks_all):
311 # Note all selected objects first.
312 change_objects_all = []
313 for atom in bpy.context.selected_objects:
314 change_objects_all.append(atom)
316 # This is very important now: If there are dupliverts structures, note
317 # only the parents and NOT the children! Otherwise the double work is
318 # done or the system can even crash if objects are deleted. - The
319 # chidlren are accessed anyways (see below).
320 change_objects = []
321 for atom in change_objects_all:
322 if atom.parent != None:
323 FLAG = False
324 for atom2 in change_objects:
325 if atom2 == atom.parent:
326 FLAG = True
327 if FLAG == False:
328 change_objects.append(atom)
329 else:
330 change_objects.append(atom)
332 # And now, consider all objects, which are in the list 'change_objects'.
333 for atom in change_objects:
334 if len(atom.children) != 0:
335 for atom_child in atom.children:
336 if atom_child.type in {'SURFACE', 'MESH', 'META'}:
337 modify_objects(action_type,
338 atom_child,
339 radius_all,
340 radius_pm,
341 radius_type,
342 radius_type_ionic,
343 sticks_all)
344 else:
345 if atom.type in {'SURFACE', 'MESH', 'META'}:
346 modify_objects(action_type,
347 atom,
348 radius_all,
349 radius_pm,
350 radius_type,
351 radius_type_ionic,
352 sticks_all)
355 # Modifying the radius of a selected atom or stick
356 def modify_objects(action_type,
357 atom,
358 radius_all,
359 radius_pm,
360 radius_type,
361 radius_type_ionic,
362 sticks_all):
364 # Modify atom radius (in pm)
365 if action_type == "ATOM_RADIUS_PM" and "STICK" not in atom.name.upper():
366 if radius_pm[0] in atom.name:
367 atom.scale = (radius_pm[1]/100,) * 3
369 # Modify atom radius (all selected)
370 if action_type == "ATOM_RADIUS_ALL" and "STICK" not in atom.name.upper():
371 atom.scale *= radius_all
373 # Modify atom radius (type, van der Waals, atomic or ionic)
374 if action_type == "ATOM_RADIUS_TYPE" and "STICK" not in atom.name.upper():
375 for element in ELEMENTS:
376 if element.name in atom.name:
377 # For ionic radii
378 if radius_type == '3':
379 charge_states = element.radii_ionic[::2]
380 charge_radii = element.radii_ionic[1::2]
381 charge_state_chosen = int(radius_type_ionic) - 4
383 find = (lambda searchList, elem:
384 [[i for i, x in enumerate(searchList) if x == e]
385 for e in elem])
386 index = find(charge_states,[charge_state_chosen])[0]
388 # Is there a charge state?
389 if index != []:
390 atom.scale = (charge_radii[index[0]],) * 3
392 # For atomic and van der Waals radii.
393 else:
394 atom.scale = (element.radii[int(radius_type)],) * 3
396 # Modify atom sticks
397 if (action_type == "STICKS_RADIUS_ALL" and 'STICK' in atom.name.upper() and
398 ('CUP' in atom.name.upper() or
399 'CYLINDER' in atom.name.upper())):
401 # For dupliverts structures only: Make the cylinder or cup visible
402 # first, otherwise one cannot go into EDIT mode. Note that 'atom' here
403 # is in fact a 'stick' (cylinder or cup).
404 # First, identify if it is a normal cylinder object or a dupliverts
405 # structure. The identifier for a dupliverts structure is the parent's
406 # name, which includes "_sticks_mesh"
407 if "_sticks_mesh" in atom.parent.name:
408 atom.hide_set(False)
410 bpy.context.view_layer.objects.active = atom
411 bpy.ops.object.mode_set(mode='EDIT', toggle=False)
412 bm = bmesh.from_edit_mesh(atom.data)
414 locations = []
415 for v in bm.verts:
416 locations.append(v.co)
418 center = Vector((0.0,0.0,0.0))
419 center = sum([location for location in locations], center)/len(locations)
421 radius = sum([(loc[0]-center[0])**2+(loc[1]-center[1])**2
422 for loc in locations], 0)
423 radius_new = radius * sticks_all
425 for v in bm.verts:
426 v.co[0] = ((v.co[0] - center[0]) / radius) * radius_new + center[0]
427 v.co[1] = ((v.co[1] - center[1]) / radius) * radius_new + center[1]
429 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
430 # Hide again the representative stick (cylinder or cup) if it is a
431 # dupliverts structure.
432 if "_sticks_mesh" in atom.parent.name:
433 atom.hide_set(True)
435 bpy.context.view_layer.objects.active = None
437 # Change the atom objects
438 if action_type == "ATOM_REPLACE_OBJ" and "STICK" not in atom.name.upper():
440 scn = bpy.context.scene.atom_blend
442 material = atom.active_material
443 new_material = draw_obj_material(scn.replace_objs_material, material)
445 # Special object (like halo, etc.)
446 if scn.replace_objs_special != '0':
447 atom = draw_obj_special(scn.replace_objs_special, atom)
448 # Standard geometrical objects
449 else:
450 # If the atom shape shall not be changed, then:
451 if scn.replace_objs == '0':
452 atom.active_material = new_material
453 # If the atom shape shall change, then:
454 else:
455 atom = draw_obj(scn.replace_objs, atom, new_material)
457 # Find the sticks, if present.
458 sticks_cylinder, sticks_cup = find_sticks_of_atom(atom)
460 # Dupliverts sticks
461 if sticks_cylinder != None and sticks_cup != None:
462 sticks_cylinder.active_material = new_material
463 sticks_cup.active_material = new_material
464 if sticks_cylinder != None and sticks_cup == None:
465 # Normal sticks
466 if type(sticks_cylinder) == list:
467 for stick in sticks_cylinder:
468 stick.active_material = new_material
469 # Skin sticks
470 else:
471 sticks_cylinder.active_material = new_material
473 # If the atom is the representative ball of a dupliverts structure,
474 # then make it invisible.
475 if atom.parent != None:
476 atom.hide_set(True)
478 # Default shape and colors for atoms
479 if action_type == "ATOM_DEFAULT_OBJ" and "STICK" not in atom.name.upper():
481 scn = bpy.context.scene.atom_blend
483 # We first obtain the element form the list of elements.
484 for element in ELEMENTS:
485 if element.name in atom.name:
486 break
488 # Create now a new material with normal properties. Note that the
489 # 'normal material' initially used during the import could have been
490 # deleted by the user. This is why we create a new one.
491 if "vacancy" in atom.name.lower():
492 new_material = draw_obj_material('2', atom.active_material)
493 else:
494 new_material = draw_obj_material('1', atom.active_material)
495 # Assign now the correct color.
496 mat_P_BSDF = next(n for n in new_material.node_tree.nodes
497 if n.type == "BSDF_PRINCIPLED")
498 mat_P_BSDF.inputs['Base Color'].default_value = element.color
499 new_material.name = element.name + "_normal"
501 # Create a new atom because the current atom might have any kind
502 # of shape. For this, we use a definition from below since it also
503 # deletes the old atom.
504 if "vacancy" in atom.name.lower():
505 new_atom = draw_obj('2', atom, new_material)
506 else:
507 new_atom = draw_obj('1b', atom, new_material)
509 # Now assign the material properties, name and size.
510 new_atom.active_material = new_material
511 new_atom.name = element.name + "_ball"
512 new_atom.scale = (element.radii[0],) * 3
514 # Find the sticks, if present.
515 sticks_cylinder, sticks_cup = find_sticks_of_atom(new_atom)
517 # Dupliverts sticks
518 if sticks_cylinder != None and sticks_cup != None:
519 sticks_cylinder.active_material = new_material
520 sticks_cup.active_material = new_material
521 if sticks_cylinder != None and sticks_cup == None:
522 # Normal sticks
523 if type(sticks_cylinder) == list:
524 for stick in sticks_cylinder:
525 stick.active_material = new_material
526 # Skin sticks
527 else:
528 sticks_cylinder.active_material = new_material
531 # Separating atoms from a dupliverts structure.
532 def separate_atoms(scn):
534 # Get the mesh.
535 mesh = bpy.context.edit_object
537 # Do nothing if it is not a dupliverts structure.
538 if not mesh.instance_type == "VERTS":
539 return {'FINISHED'}
541 # This is the name of the mesh
542 mesh_name = mesh.name
543 # Get the collection
544 coll = mesh.users_collection[0]
546 # Get the coordinates of the selected vertices (atoms)
547 bm = bmesh.from_edit_mesh(mesh.data)
548 locations = []
549 for v in bm.verts:
550 if v.select:
551 locations.append(mesh.matrix_world @ v.co)
553 # Free memory
554 bm.free()
556 # Delete already the selected vertices
557 bpy.ops.mesh.delete(type='VERT')
559 # Find the representative ball within the collection.
560 for obj in coll.objects:
561 if obj.parent != None:
562 if obj.parent.name == mesh_name:
563 break
565 # Create balls and put them at the places where the vertices (atoms) have
566 # been before.
567 for location in locations:
568 obj_dupli = obj.copy()
569 obj_dupli.data = obj.data.copy()
570 obj_dupli.parent = None
571 coll.objects.link(obj_dupli)
572 obj_dupli.location = location
573 obj_dupli.name = obj.name + "_sep"
574 # Do not hide the object!
575 obj_dupli.hide_set(False)
577 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
578 bpy.context.view_layer.objects.active = mesh
581 # Prepare a new material
582 def draw_obj_material(material_type, material):
584 mat_P_BSDF_default = next(n for n in material.node_tree.nodes
585 if n.type == "BSDF_PRINCIPLED")
586 default_color = mat_P_BSDF_default.inputs['Base Color'].default_value
588 if material_type == '0': # Unchanged
589 material_new = material
590 if material_type == '1': # Normal
591 # We create again the 'normal' material. Why? It's because the old
592 # one could have been deleted by the user during the course of the
593 # user's work in Blender ... .
594 material_new = bpy.data.materials.new(material.name + "_normal")
595 material_new.use_nodes = True
596 mat_P_BSDF = next(n for n in material_new.node_tree.nodes
597 if n.type == "BSDF_PRINCIPLED")
598 mat_P_BSDF.inputs['Base Color'].default_value = default_color
599 mat_P_BSDF.inputs['Metallic'].default_value = 0.0
600 mat_P_BSDF.inputs['Specular'].default_value = 0.5
601 mat_P_BSDF.inputs['Roughness'].default_value = 0.5
602 mat_P_BSDF.inputs['Clearcoat Roughness'].default_value = 0.03
603 mat_P_BSDF.inputs['IOR'].default_value = 1.45
604 mat_P_BSDF.inputs['Transmission'].default_value = 0.0
605 mat_P_BSDF.inputs['Transmission Roughness'].default_value = 0.0
606 mat_P_BSDF.inputs['Alpha'].default_value = 1.0
607 # Some additional stuff for eevee.
608 material_new.blend_method = 'OPAQUE'
609 material_new.shadow_method = 'OPAQUE'
610 if material_type == '2': # Transparent
611 material_new = bpy.data.materials.new(material.name + "_transparent")
612 material_new.use_nodes = True
613 mat_P_BSDF = next(n for n in material_new.node_tree.nodes
614 if n.type == "BSDF_PRINCIPLED")
615 mat_P_BSDF.inputs['Base Color'].default_value = default_color
616 mat_P_BSDF.inputs['Metallic'].default_value = 0.0
617 mat_P_BSDF.inputs['Specular'].default_value = 0.15
618 mat_P_BSDF.inputs['Roughness'].default_value = 0.2
619 mat_P_BSDF.inputs['Clearcoat Roughness'].default_value = 0.37
620 mat_P_BSDF.inputs['IOR'].default_value = 1.45
621 mat_P_BSDF.inputs['Transmission'].default_value = 0.8
622 mat_P_BSDF.inputs['Transmission Roughness'].default_value = 0.0
623 mat_P_BSDF.inputs['Alpha'].default_value = 0.4
624 # Some additional stuff for eevee.
625 material_new.blend_method = 'HASHED'
626 material_new.shadow_method = 'HASHED'
627 material_new.use_backface_culling = False
628 if material_type == '3': # Reflecting
629 material_new = bpy.data.materials.new(material.name + "_reflecting")
630 material_new.use_nodes = True
631 mat_P_BSDF = next(n for n in material_new.node_tree.nodes
632 if n.type == "BSDF_PRINCIPLED")
633 mat_P_BSDF.inputs['Base Color'].default_value = default_color
634 mat_P_BSDF.inputs['Metallic'].default_value = 0.7
635 mat_P_BSDF.inputs['Specular'].default_value = 0.15
636 mat_P_BSDF.inputs['Roughness'].default_value = 0.1
637 mat_P_BSDF.inputs['Clearcoat Roughness'].default_value = 0.5
638 mat_P_BSDF.inputs['IOR'].default_value = 0.8
639 mat_P_BSDF.inputs['Transmission'].default_value = 0.0
640 mat_P_BSDF.inputs['Transmission Roughness'].default_value = 0.0
641 mat_P_BSDF.inputs['Alpha'].default_value = 1.0
642 # Some additional stuff for eevee.
643 material_new.blend_method = 'OPAQUE'
644 material_new.shadow_method = 'OPAQUE'
645 if material_type == '4': # Transparent + reflecting
646 material_new = bpy.data.materials.new(material.name + "_trans+refl")
647 material_new.use_nodes = True
648 mat_P_BSDF = next(n for n in material_new.node_tree.nodes
649 if n.type == "BSDF_PRINCIPLED")
650 mat_P_BSDF.inputs['Base Color'].default_value = default_color
651 mat_P_BSDF.inputs['Metallic'].default_value = 0.5
652 mat_P_BSDF.inputs['Specular'].default_value = 0.15
653 mat_P_BSDF.inputs['Roughness'].default_value = 0.05
654 mat_P_BSDF.inputs['Clearcoat Roughness'].default_value = 0.37
655 mat_P_BSDF.inputs['IOR'].default_value = 1.45
656 mat_P_BSDF.inputs['Transmission'].default_value = 0.6
657 mat_P_BSDF.inputs['Transmission Roughness'].default_value = 0.0
658 mat_P_BSDF.inputs['Alpha'].default_value = 0.6
659 # Some additional stuff for eevee.
660 material_new.blend_method = 'HASHED'
661 material_new.shadow_method = 'HASHED'
662 material_new.use_backface_culling = False
664 # Always, when the material is changed, a new name is created. Note that
665 # this makes sense: Imagine, an other object uses the same material as the
666 # selected one. After changing the material of the selected object the old
667 # material should certainly not change and remain the same.
668 if material_type in {'1','2','3','4'}:
669 if "_repl" in material.name:
670 pos = material.name.rfind("_repl")
671 if material.name[pos+5:].isdigit():
672 counter = int(material.name[pos+5:])
673 material_new.name = material.name[:pos]+"_repl"+str(counter+1)
674 else:
675 material_new.name = material.name+"_repl1"
676 else:
677 material_new.name = material.name+"_repl1"
678 material_new.diffuse_color = material.diffuse_color
680 return material_new
683 # Get the collection of an object.
684 def get_collection_object(obj):
686 coll_all = obj.users_collection
687 if len(coll_all) > 0:
688 coll = coll_all[0]
689 else:
690 coll = bpy.context.scene.collection
692 return coll
695 # Find the sticks of an atom.
696 def find_sticks_of_atom(atom):
698 # Initialization of the stick objects 'cylinder' and 'cup'.
699 sticks_cylinder = None
700 sticks_cup = None
702 # This is for dupliverts structures.
703 if atom.parent != None:
705 D = bpy.data
706 C = bpy.context
708 # Get a list of all scenes.
709 cols_scene = [c for c in D.collections if C.scene.user_of_id(c)]
711 # This is the collection where the atom is inside.
712 col_atom = atom.parent.users_collection[0]
714 # Get the parent collection of the latter collection.
715 col_parent = [c for c in cols_scene if c.user_of_id(col_atom)][0]
717 # Get **all** children collections inside this parent collection.
718 parent_childrens = col_parent.children_recursive
720 # This is for dupliverts stick structures now: for each child
721 # collection do:
722 for child in parent_childrens:
723 # It should not have the name of the atom collection.
724 if child.name != col_atom.name:
725 # If the sticks are inside then ...
726 if "sticks" in child.name:
727 # For all objects do ...
728 for obj in child.objects:
729 # If the stick objects are inside then note them.
730 if "sticks_cylinder" in obj.name:
731 sticks_cylinder = obj
732 if "sticks_cup" in obj.name:
733 sticks_cup = obj
735 # No dupliverts stick structures found? Then lets search for
736 # 'normal' and 'skin' sticks. Such sticks are in the collection
737 # 'Sticks' of the atomic structure.
738 if sticks_cylinder == None and sticks_cup == None:
740 # Get the grandparent collection of the parent collection.
741 col_grandparent = [c for c in cols_scene if c.user_of_id(col_parent)][0]
743 # Skin sticks:
744 list_objs = col_grandparent.objects
745 for obj in list_objs:
746 if "Sticks" in obj.name:
747 sticks_cylinder = obj
748 break
750 # Normal sticks
751 if sticks_cylinder == None:
752 # For each child collection do:
753 for child in col_grandparent.children_recursive:
754 # If the sticks are inside then ...
755 if "Sticks_cylinders" in child.name:
756 sticks_cylinder = []
757 for obj in child.objects:
758 sticks_cylinder.append(obj)
759 break
761 # Return the stick objects 'cylinder' and 'cup'.
763 # Dupliverts sticks => sticks_cylinder = 1, sticks_cup = 1
764 # Skin sticks => sticks_cylinder = 1, sticks_cup = None
765 # Normal sticks => sticks_cylinder = [n], sticks_cup = None
766 return sticks_cylinder, sticks_cup
769 # Draw an object (e.g. cube, sphere, cylinder, ...)
770 def draw_obj(atom_shape, atom, new_material):
772 # No change
773 if atom_shape == '0':
774 return None
776 if atom_shape == '1a': #Sphere mesh
777 bpy.ops.mesh.primitive_uv_sphere_add(
778 segments=32,
779 ring_count=32,
780 radius=1,
781 align='WORLD',
782 enter_editmode=False,
783 location=atom.location,
784 rotation=(0, 0, 0))
785 if atom_shape == '1b': #Sphere NURBS
786 bpy.ops.surface.primitive_nurbs_surface_sphere_add(
787 align='WORLD',
788 enter_editmode=False,
789 location=atom.location,
790 rotation=(0.0, 0.0, 0.0))
791 if atom_shape == '2': #Cube
792 bpy.ops.mesh.primitive_cube_add(
793 align='WORLD',
794 enter_editmode=False,
795 location=atom.location,
796 rotation=(0.0, 0.0, 0.0))
797 if atom_shape == '3': #Plane
798 bpy.ops.mesh.primitive_plane_add(
799 align='WORLD',
800 enter_editmode=False,
801 location=atom.location,
802 rotation=(0.0, 0.0, 0.0))
803 if atom_shape == '4a': #Circle
804 bpy.ops.mesh.primitive_circle_add(
805 vertices=32,
806 radius=1,
807 fill_type='NOTHING',
808 align='WORLD',
809 enter_editmode=False,
810 location=atom.location,
811 rotation=(0, 0, 0))
812 if atom_shape == '4b': #Circle NURBS
813 bpy.ops.surface.primitive_nurbs_surface_circle_add(
814 align='WORLD',
815 enter_editmode=False,
816 location=atom.location,
817 rotation=(0, 0, 0))
818 if atom_shape in {'5a','5b','5c','5d','5e'}: #Icosphere
819 index = {'5a':1,'5b':2,'5c':3,'5d':4,'5e':5}
820 bpy.ops.mesh.primitive_ico_sphere_add(
821 subdivisions=int(index[atom_shape]),
822 radius=1,
823 align='WORLD',
824 enter_editmode=False,
825 location=atom.location,
826 rotation=(0, 0, 0))
827 if atom_shape == '6a': #Cylinder
828 bpy.ops.mesh.primitive_cylinder_add(
829 vertices=32,
830 radius=1,
831 depth=2,
832 end_fill_type='NGON',
833 align='WORLD',
834 enter_editmode=False,
835 location=atom.location,
836 rotation=(0, 0, 0))
837 if atom_shape == '6b': #Cylinder NURBS
838 bpy.ops.surface.primitive_nurbs_surface_cylinder_add(
839 align='WORLD',
840 enter_editmode=False,
841 location=atom.location,
842 rotation=(0, 0, 0))
843 if atom_shape == '7': #Cone
844 bpy.ops.mesh.primitive_cone_add(
845 vertices=32,
846 radius1=1,
847 radius2=0,
848 depth=2,
849 end_fill_type='NGON',
850 align='WORLD',
851 enter_editmode=False,
852 location=atom.location,
853 rotation=(0, 0, 0))
854 if atom_shape == '8a': #Torus
855 bpy.ops.mesh.primitive_torus_add(
856 rotation=(0, 0, 0),
857 location=atom.location,
858 align='WORLD',
859 major_radius=1,
860 minor_radius=0.25,
861 major_segments=48,
862 minor_segments=12,
863 abso_major_rad=1,
864 abso_minor_rad=0.5)
865 if atom_shape == '8b': #Torus NURBS
866 bpy.ops.surface.primitive_nurbs_surface_torus_add(
867 align='WORLD',
868 enter_editmode=False,
869 location=atom.location,
870 rotation=(0, 0, 0))
872 new_atom = bpy.context.view_layer.objects.active
873 new_atom.scale = atom.scale + Vector((0.0,0.0,0.0))
874 new_atom.name = atom.name
875 new_atom.select_set(True)
877 new_atom.active_material = new_material
879 # If it is the representative object of a duplivert structure then
880 # transfer the parent and hide the new object.
881 if atom.parent != None:
882 new_atom.parent = atom.parent
883 new_atom.hide_set(True)
885 # Note the collection where the old object was placed into.
886 coll_old_atom = get_collection_object(atom)
888 # Note the collection where the new object was placed into.
889 coll_new_atom_past = get_collection_object(new_atom)
891 # If it is not the same collection then ...
892 if coll_new_atom_past != coll_old_atom:
893 # Put the new object into the collection of the old object and ...
894 coll_old_atom.objects.link(new_atom)
895 # ... unlink the new atom from its original collection.
896 coll_new_atom_past.objects.unlink(new_atom)
898 # If necessary, remove the childrens of the old object.
899 for child in atom.children:
900 bpy.ops.object.select_all(action='DESELECT')
901 child.hide_set(True)
902 child.select_set(True)
903 child.parent = None
904 coll_child = get_collection_object(child)
905 coll_child.objects.unlink(child)
906 bpy.ops.object.delete()
908 # Deselect everything
909 bpy.ops.object.select_all(action='DESELECT')
910 # Make the old atom visible.
911 atom.hide_set(True)
912 # Select the old atom.
913 atom.select_set(True)
914 # Remove the parent if necessary.
915 atom.parent = None
916 # Unlink the old object from the collection.
917 coll_old_atom.objects.unlink(atom)
918 # Delete the old atom
919 bpy.ops.object.delete()
921 #if "_F2+_center" or "_F+_center" or "_F0_center" in coll_old_atom:
922 # print("Delete the collection")
924 return new_atom
927 # Draw a special object (e.g. halo, etc. ...)
928 def draw_obj_special(atom_shape, atom):
930 # Note the collection where 'atom' is placed into.
931 coll_atom = get_collection_object(atom)
933 # Now, create a collection for the new objects
934 coll_new = atom.name
935 # Create the new collection and ...
936 coll_new = bpy.data.collections.new(coll_new)
937 # ... link it to the collection, which contains 'atom'.
938 coll_atom.children.link(coll_new)
940 # Get the color of the selected atom.
941 material = atom.active_material
942 mat_P_BSDF_default = next(n for n in material.node_tree.nodes
943 if n.type == "BSDF_PRINCIPLED")
944 default_color = mat_P_BSDF_default.inputs['Base Color'].default_value
946 # Create first a cube
947 bpy.ops.mesh.primitive_cube_add(align='WORLD',
948 enter_editmode=False,
949 location=atom.location,
950 rotation=(0.0, 0.0, 0.0))
951 cube = bpy.context.view_layer.objects.active
952 cube.scale = atom.scale + Vector((0.0,0.0,0.0))
953 cube.select_set(True)
955 # F2+ center
956 if atom_shape == '1':
957 cube.name = atom.name + "_F2+_vac"
959 # New material for this cube
960 material_new = bpy.data.materials.new(atom.name + "_F2+_vac")
961 material_new.use_nodes = True
962 mat_P_BSDF = next(n for n in material_new.node_tree.nodes
963 if n.type == "BSDF_PRINCIPLED")
964 mat_P_BSDF.inputs['Base Color'].default_value = default_color
965 mat_P_BSDF.inputs['Metallic'].default_value = 0.7
966 mat_P_BSDF.inputs['Specular'].default_value = 0.0
967 mat_P_BSDF.inputs['Roughness'].default_value = 0.65
968 mat_P_BSDF.inputs['Clearcoat Roughness'].default_value = 0.0
969 mat_P_BSDF.inputs['IOR'].default_value = 1.45
970 mat_P_BSDF.inputs['Transmission'].default_value = 0.6
971 mat_P_BSDF.inputs['Transmission Roughness'].default_value = 0.5
972 mat_P_BSDF.inputs['Alpha'].default_value = 0.6
973 # Some additional stuff for eevee.
974 material_new.blend_method = 'HASHED'
975 material_new.shadow_method = 'HASHED'
976 material_new.use_backface_culling = False
977 cube.active_material = material_new
979 # Put a point lamp inside the defect.
980 lamp_data = bpy.data.lights.new(name=atom.name + "_F2+_lamp", type="POINT")
981 lamp_data.distance = atom.scale[0] * 2.0
982 lamp_data.energy = 2000.0
983 lamp_data.color = (0.8, 0.8, 0.8)
984 lamp = bpy.data.objects.new(atom.name + "_F2+_lamp", lamp_data)
985 lamp.location = Vector((0.0, 0.0, 0.0))
986 bpy.context.collection.objects.link(lamp)
987 lamp.parent = cube
989 # The new 'atom' is the F2+ defect
990 new_atom = cube
992 # Note the collection where all the new objects were placed into.
993 # We use only one object, the cube
994 coll_ori = get_collection_object(cube)
996 # If it is not the same collection then ...
997 if coll_ori != coll_new:
998 # Put all new objects into the new collection and ...
999 coll_new.objects.link(cube)
1000 coll_new.objects.link(lamp)
1001 # ... unlink them from their original collection.
1002 coll_ori.objects.unlink(cube)
1003 coll_ori.objects.unlink(lamp)
1005 coll_new.name = atom.name + "_F2+_center"
1007 if atom.parent != None:
1008 cube.parent = atom.parent
1009 cube.hide_set(True)
1010 lamp.hide_set(True)
1012 # F+ center
1013 if atom_shape == '2':
1014 cube.name = atom.name + "_F2+_vac"
1016 # New material for this cube
1017 material_new = bpy.data.materials.new(atom.name + "_F2+_vac")
1018 material_new.use_nodes = True
1019 mat_P_BSDF = next(n for n in material_new.node_tree.nodes
1020 if n.type == "BSDF_PRINCIPLED")
1021 mat_P_BSDF.inputs['Base Color'].default_value = [0.0, 0.0, 0.8, 1.0]
1022 mat_P_BSDF.inputs['Metallic'].default_value = 0.7
1023 mat_P_BSDF.inputs['Specular'].default_value = 0.0
1024 mat_P_BSDF.inputs['Roughness'].default_value = 0.65
1025 mat_P_BSDF.inputs['Clearcoat Roughness'].default_value = 0.0
1026 mat_P_BSDF.inputs['IOR'].default_value = 1.45
1027 mat_P_BSDF.inputs['Transmission'].default_value = 0.6
1028 mat_P_BSDF.inputs['Transmission Roughness'].default_value = 0.5
1029 mat_P_BSDF.inputs['Alpha'].default_value = 0.6
1030 # Some additional stuff for eevee.
1031 material_new.blend_method = 'HASHED'
1032 material_new.shadow_method = 'HASHED'
1033 material_new.use_backface_culling = False
1034 cube.active_material = material_new
1036 # Create now an electron
1037 scale = atom.scale / 10.0
1038 bpy.ops.surface.primitive_nurbs_surface_sphere_add(
1039 align='WORLD',
1040 enter_editmode=False,
1041 location=(0.0, 0.0, 0.0),
1042 rotation=(0.0, 0.0, 0.0))
1043 electron = bpy.context.view_layer.objects.active
1044 electron.scale = scale
1045 electron.name = atom.name + "_F+_electron"
1046 electron.parent = cube
1047 # New material for the electron
1048 material_electron = bpy.data.materials.new(atom.name + "_F+-center")
1049 material_electron.use_nodes = True
1050 mat_P_BSDF = next(n for n in material_electron.node_tree.nodes
1051 if n.type == "BSDF_PRINCIPLED")
1052 mat_P_BSDF.inputs['Base Color'].default_value = [0.0, 0.0, 0.8, 1.0]
1053 mat_P_BSDF.inputs['Metallic'].default_value = 0.8
1054 mat_P_BSDF.inputs['Specular'].default_value = 0.0
1055 mat_P_BSDF.inputs['Roughness'].default_value = 0.3
1056 mat_P_BSDF.inputs['Clearcoat Roughness'].default_value = 0.0
1057 mat_P_BSDF.inputs['IOR'].default_value = 1.45
1058 mat_P_BSDF.inputs['Transmission'].default_value = 0.6
1059 mat_P_BSDF.inputs['Transmission Roughness'].default_value = 0.5
1060 mat_P_BSDF.inputs['Alpha'].default_value = 1.0
1061 # Some additional stuff for eevee.
1062 material_electron.blend_method = 'OPAQUE'
1063 material_electron.shadow_method = 'OPAQUE'
1064 material_electron.use_backface_culling = False
1065 electron.active_material = material_electron
1067 # Put a point lamp inside the electron
1068 lamp_data = bpy.data.lights.new(name=atom.name + "_F+_lamp", type="POINT")
1069 lamp_data.distance = atom.scale[0] * 2.0
1070 lamp_data.energy = 100000.0
1071 lamp_data.color = (0.0, 0.0, 0.8)
1072 lamp = bpy.data.objects.new(atom.name + "_F+_lamp", lamp_data)
1073 lamp.location = Vector((scale[0]*1.5, 0.0, 0.0))
1074 bpy.context.collection.objects.link(lamp)
1075 lamp.parent = cube
1077 # The new 'atom' is the F+ defect complex + lamp
1078 new_atom = cube
1080 # Note the collection where all the new objects were placed into.
1081 # We use only one object, the cube
1082 coll_ori = get_collection_object(cube)
1084 # If it is not the same collection then ...
1085 if coll_ori != coll_new:
1086 # Put all new objects into the new collection and ...
1087 coll_new.objects.link(cube)
1088 coll_new.objects.link(electron)
1089 coll_new.objects.link(lamp)
1090 # ... unlink them from their original collection.
1091 coll_ori.objects.unlink(cube)
1092 coll_ori.objects.unlink(electron)
1093 coll_ori.objects.unlink(lamp)
1095 coll_new.name = atom.name + "_F+_center"
1097 if atom.parent != None:
1098 cube.parent = atom.parent
1099 cube.hide_set(True)
1100 electron.hide_set(True)
1101 lamp.hide_set(True)
1103 # F0 center
1104 if atom_shape == '3':
1105 cube.name = atom.name + "_F2+_vac"
1107 # New material for this cube
1108 material_new = bpy.data.materials.new(atom.name + "_F2+_vac")
1109 material_new.use_nodes = True
1110 mat_P_BSDF = next(n for n in material_new.node_tree.nodes
1111 if n.type == "BSDF_PRINCIPLED")
1112 mat_P_BSDF.inputs['Base Color'].default_value = [0.8, 0.0, 0.0, 1.0]
1113 mat_P_BSDF.inputs['Metallic'].default_value = 0.7
1114 mat_P_BSDF.inputs['Specular'].default_value = 0.0
1115 mat_P_BSDF.inputs['Roughness'].default_value = 0.65
1116 mat_P_BSDF.inputs['Clearcoat Roughness'].default_value = 0.0
1117 mat_P_BSDF.inputs['IOR'].default_value = 1.45
1118 mat_P_BSDF.inputs['Transmission'].default_value = 0.6
1119 mat_P_BSDF.inputs['Transmission Roughness'].default_value = 0.5
1120 mat_P_BSDF.inputs['Alpha'].default_value = 0.6
1121 # Some additional stuff for eevee.
1122 material_new.blend_method = 'HASHED'
1123 material_new.shadow_method = 'HASHED'
1124 material_new.use_backface_culling = False
1125 cube.active_material = material_new
1127 # Create now two electrons ... .
1128 scale = atom.scale / 10.0
1129 bpy.ops.surface.primitive_nurbs_surface_sphere_add(
1130 align='WORLD',
1131 enter_editmode=False,
1132 location=(scale[0]*1.5,0.0,0.0),
1133 rotation=(0.0, 0.0, 0.0))
1134 electron1 = bpy.context.view_layer.objects.active
1135 electron1.scale = scale
1136 electron1.name = atom.name + "_F0_electron_1"
1137 electron1.parent = cube
1138 bpy.ops.surface.primitive_nurbs_surface_sphere_add(
1139 align='WORLD',
1140 enter_editmode=False,
1141 location=(-scale[0]*1.5,0.0,0.0),
1142 rotation=(0.0, 0.0, 0.0))
1143 electron2 = bpy.context.view_layer.objects.active
1144 electron2.scale = scale
1145 electron2.name = atom.name + "_F0_electron_2"
1146 electron2.parent = cube
1147 # Create a new material for the two electrons.
1148 material_electron = bpy.data.materials.new(atom.name + "_F0-center")
1149 material_electron.use_nodes = True
1150 mat_P_BSDF = next(n for n in material_electron.node_tree.nodes
1151 if n.type == "BSDF_PRINCIPLED")
1152 mat_P_BSDF.inputs['Base Color'].default_value = [0.0, 0.0, 0.8, 1.0]
1153 mat_P_BSDF.inputs['Metallic'].default_value = 0.8
1154 mat_P_BSDF.inputs['Specular'].default_value = 0.0
1155 mat_P_BSDF.inputs['Roughness'].default_value = 0.3
1156 mat_P_BSDF.inputs['Clearcoat Roughness'].default_value = 0.0
1157 mat_P_BSDF.inputs['IOR'].default_value = 1.45
1158 mat_P_BSDF.inputs['Transmission'].default_value = 0.6
1159 mat_P_BSDF.inputs['Transmission Roughness'].default_value = 0.5
1160 mat_P_BSDF.inputs['Alpha'].default_value = 1.0
1161 # Some additional stuff for eevee.
1162 material_electron.blend_method = 'OPAQUE'
1163 material_electron.shadow_method = 'OPAQUE'
1164 material_electron.use_backface_culling = False
1165 # We assign the materials to the two electrons.
1166 electron1.active_material = material_electron
1167 electron2.active_material = material_electron
1169 # Put two point lamps inside the electrons.
1170 lamp1_data = bpy.data.lights.new(name=atom.name + "_F0_lamp_1", type="POINT")
1171 lamp1_data.distance = atom.scale[0] * 2.0
1172 lamp1_data.energy = 20000.0
1173 lamp1_data.color = (0.8, 0.0, 0.0)
1174 lamp1 = bpy.data.objects.new(atom.name + "_F0_lamp", lamp1_data)
1175 lamp1.location = Vector((scale[0]*1.5, 0.0, 0.0))
1176 bpy.context.collection.objects.link(lamp1)
1177 lamp1.parent = cube
1178 lamp2_data = bpy.data.lights.new(name=atom.name + "_F0_lamp_2", type="POINT")
1179 lamp2_data.distance = atom.scale[0] * 2.0
1180 lamp2_data.energy = 20000.0
1181 lamp2_data.color = (0.8, 0.0, 0.0)
1182 lamp2 = bpy.data.objects.new(atom.name + "_F0_lamp", lamp2_data)
1183 lamp2.location = Vector((-scale[0]*1.5, 0.0, 0.0))
1184 bpy.context.collection.objects.link(lamp2)
1185 lamp2.parent = cube
1187 # The new 'atom' is the F0 defect complex + lamps
1188 new_atom = cube
1190 # Note the collection where all the new objects were placed into.
1191 # We use only one object, the cube
1192 coll_ori = get_collection_object(cube)
1194 # If it is not the same collection then ...
1195 if coll_ori != coll_new:
1196 # Put all new objects into the collection of 'atom' and ...
1197 coll_new.objects.link(cube)
1198 coll_new.objects.link(electron1)
1199 coll_new.objects.link(electron2)
1200 coll_new.objects.link(lamp1)
1201 coll_new.objects.link(lamp2)
1202 # ... unlink them from their original collection.
1203 coll_ori.objects.unlink(cube)
1204 coll_ori.objects.unlink(electron1)
1205 coll_ori.objects.unlink(electron2)
1206 coll_ori.objects.unlink(lamp1)
1207 coll_ori.objects.unlink(lamp2)
1209 coll_new.name = atom.name + "_F0_center"
1211 if atom.parent != None:
1212 cube.parent = atom.parent
1213 cube.hide_set(True)
1214 electron1.hide_set(True)
1215 electron2.hide_set(True)
1216 lamp1.hide_set(True)
1217 lamp2.hide_set(True)
1219 # Deselect everything
1220 bpy.ops.object.select_all(action='DESELECT')
1221 # Make the old atom visible.
1222 atom.hide_set(True)
1223 # Select the old atom.
1224 atom.select_set(True)
1225 # Remove the parent if necessary.
1226 atom.parent = None
1227 # Unlink the old object from the collection.
1228 coll_atom.objects.unlink(atom)
1229 # Delete the old atom
1230 bpy.ops.object.delete()
1232 return new_atom
1235 # Initialization of the list 'ELEMENTS'.
1236 def read_elements():
1238 del ELEMENTS[:]
1240 for item in ELEMENTS_DEFAULT:
1242 # All three radii into a list
1243 radii = [item[4],item[5],item[6]]
1244 # The handling of the ionic radii will be done later. So far, it is an
1245 # empty list.
1246 radii_ionic = item[7:]
1248 li = ElementProp(item[0], item[1], item[2], item[3], radii, radii_ionic, [], [])
1250 ELEMENTS.append(li)
1253 # Custom data file: changing color and radii by using the list 'ELEMENTS'.
1254 def custom_datafile_change_atom_props():
1256 for atom in bpy.context.selected_objects:
1258 FLAG = False
1259 if len(atom.children) != 0:
1260 child = atom.children[0]
1261 if child.type in {'SURFACE', 'MESH', 'META'}:
1262 for element in ELEMENTS:
1263 if element.name in atom.name:
1264 obj = child
1265 e = element
1266 FLAG = True
1267 else:
1268 if atom.type in {'SURFACE', 'MESH', 'META'}:
1269 for element in ELEMENTS:
1270 if element.name in atom.name:
1271 obj = atom
1272 e = element
1273 FLAG = True
1275 if FLAG:
1276 obj.scale = (e.radii[0],) * 3
1277 mat = obj.active_material
1278 mat_P_BSDF = next(n for n in mat.node_tree.nodes
1279 if n.type == "BSDF_PRINCIPLED")
1281 mat_P_BSDF.inputs['Base Color'].default_value = e.color
1282 mat_P_BSDF.subsurface_method = e.mat_P_BSDF.Subsurface_method
1283 mat_P_BSDF.distribution = e.mat_P_BSDF.Distribution
1284 mat_P_BSDF.inputs['Subsurface'].default_value = e.mat_P_BSDF.Subsurface
1285 mat_P_BSDF.inputs['Subsurface Color'].default_value = e.mat_P_BSDF.Subsurface_color
1286 mat_P_BSDF.inputs['Subsurface Radius'].default_value = e.mat_P_BSDF.Subsurface_radius
1287 mat_P_BSDF.inputs['Metallic'].default_value = e.mat_P_BSDF.Metallic
1288 mat_P_BSDF.inputs['Specular'].default_value = e.mat_P_BSDF.Specular
1289 mat_P_BSDF.inputs['Specular Tint'].default_value = e.mat_P_BSDF.Specular_tilt
1290 mat_P_BSDF.inputs['Roughness'].default_value = e.mat_P_BSDF.Roughness
1291 mat_P_BSDF.inputs['Anisotropic'].default_value = e.mat_P_BSDF.Anisotropic
1292 mat_P_BSDF.inputs['Anisotropic Rotation'].default_value = e.mat_P_BSDF.Anisotropic_rotation
1293 mat_P_BSDF.inputs['Sheen'].default_value = e.mat_P_BSDF.Sheen
1294 mat_P_BSDF.inputs['Sheen Tint'].default_value = e.mat_P_BSDF.Sheen_tint
1295 mat_P_BSDF.inputs['Clearcoat'].default_value = e.mat_P_BSDF.Clearcoat
1296 mat_P_BSDF.inputs['Clearcoat Roughness'].default_value = e.mat_P_BSDF.Clearcoat_rough
1297 mat_P_BSDF.inputs['IOR'].default_value = e.mat_P_BSDF.IOR
1298 mat_P_BSDF.inputs['Transmission'].default_value = e.mat_P_BSDF.Trans
1299 mat_P_BSDF.inputs['Transmission Roughness'].default_value = e.mat_P_BSDF.Trans_rough
1300 mat_P_BSDF.inputs['Emission'].default_value = e.mat_P_BSDF.Emission
1301 mat_P_BSDF.inputs['Emission Strength'].default_value = e.mat_P_BSDF.Emission_strength
1302 mat_P_BSDF.inputs['Alpha'].default_value = e.mat_P_BSDF.Alpha
1304 mat.use_backface_culling = e.mat_Eevee.use_backface
1305 mat.blend_method = e.mat_Eevee.blend_method
1306 mat.shadow_method = e.mat_Eevee.shadow_method
1307 mat.alpha_threshold = e.mat_Eevee.clip_threshold
1308 mat.use_screen_refraction = e.mat_Eevee.use_screen_refraction
1309 mat.refraction_depth = e.mat_Eevee.refraction_depth
1310 mat.use_sss_translucency = e.mat_Eevee.use_sss_translucency
1311 mat.pass_index = e.mat_Eevee.pass_index
1313 FLAG = False
1315 bpy.ops.object.select_all(action='DESELECT')
1318 # Reading a custom data file and modifying the list 'ELEMENTS'.
1319 def custom_datafile(path_datafile):
1321 if path_datafile == "":
1322 return False
1324 path_datafile = bpy.path.abspath(path_datafile)
1326 if os.path.isfile(path_datafile) == False:
1327 return False
1329 # The whole list gets deleted! We build it new.
1330 del ELEMENTS[:]
1332 # Read the data file, which contains all data
1333 # (atom name, radii, colors, etc.)
1334 data_file_p = open(path_datafile, "r")
1336 for line in data_file_p:
1338 if "#" == line[0]:
1339 continue
1341 if "Atom" in line:
1343 list_radii_ionic = []
1344 while True:
1346 if len(line) in [0,1]:
1347 break
1349 # Number
1350 if "Number :" in line:
1351 pos = line.rfind(':') + 1
1352 number = line[pos:].strip()
1353 # Name
1354 if "Name :" in line:
1355 pos = line.rfind(':') + 1
1356 name = line[pos:].strip()
1357 # Short name
1358 if "Short name :" in line:
1359 pos = line.rfind(':') + 1
1360 short_name = line[pos:].strip()
1361 # Color
1362 if "Color :" in line:
1363 pos = line.rfind(':') + 1
1364 color_value = line[pos:].strip().split(',')
1365 color = [float(color_value[0]),
1366 float(color_value[1]),
1367 float(color_value[2]),
1368 float(color_value[3])]
1369 # Used radius
1370 if "Radius used :" in line:
1371 pos = line.rfind(':') + 1
1372 radius_used = float(line[pos:].strip())
1373 # Covalent radius
1374 if "Radius, covalent :" in line:
1375 pos = line.rfind(':') + 1
1376 radius_covalent = float(line[pos:].strip())
1377 # Atomic radius
1378 if "Radius, atomic :" in line:
1379 pos = line.rfind(':') + 1
1380 radius_atomic = float(line[pos:].strip())
1381 if "Charge state :" in line:
1382 pos = line.rfind(':') + 1
1383 charge_state = float(line[pos:].strip())
1384 line = data_file_p.readline()
1385 pos = line.rfind(':') + 1
1386 radius_ionic = float(line[pos:].strip())
1387 list_radii_ionic.append(charge_state)
1388 list_radii_ionic.append(radius_ionic)
1390 # Some Principled BSDF properties
1393 if "P BSDF Subsurface method :" in line:
1394 pos = line.rfind(':') + 1
1395 P_BSDF_subsurface_method = line[pos:].strip()
1396 if "P BSDF Distribution :" in line:
1397 pos = line.rfind(':') + 1
1398 P_BSDF_distribution = line[pos:].strip()
1399 if "P BSDF Subsurface :" in line:
1400 pos = line.rfind(':') + 1
1401 P_BSDF_subsurface = float(line[pos:].strip())
1402 if "P BSDF Subsurface Color :" in line:
1403 pos = line.rfind(':') + 1
1404 color_value = line[pos:].strip().split(',')
1405 P_BSDF_subsurface_color = [float(color_value[0]),
1406 float(color_value[1]),
1407 float(color_value[2]),
1408 float(color_value[3])]
1409 if "P BSDF Subsurface Radius :" in line:
1410 pos = line.rfind(':') + 1
1411 radii_values = line[pos:].strip().split(',')
1412 P_BSDF_subsurface_radius = [float(color_value[0]),
1413 float(color_value[1]),
1414 float(color_value[2])]
1415 if "P BSDF Metallic :" in line:
1416 pos = line.rfind(':') + 1
1417 P_BSDF_metallic = float(line[pos:].strip())
1418 if "P BSDF Specular :" in line:
1419 pos = line.rfind(':') + 1
1420 P_BSDF_specular = float(line[pos:].strip())
1421 if "P BSDF Specular Tilt :" in line:
1422 pos = line.rfind(':') + 1
1423 P_BSDF_specular_tilt = float(line[pos:].strip())
1424 if "P BSDF Roughness :" in line:
1425 pos = line.rfind(':') + 1
1426 P_BSDF_roughness = float(line[pos:].strip())
1427 if "P BSDF Anisotropic :" in line:
1428 pos = line.rfind(':') + 1
1429 P_BSDF_anisotropic = float(line[pos:].strip())
1430 if "P BSDF Anisotropic Rotation :" in line:
1431 pos = line.rfind(':') + 1
1432 P_BSDF_anisotropic_rotation = float(line[pos:].strip())
1433 if "P BSDF Sheen : " in line:
1434 pos = line.rfind(':') + 1
1435 P_BSDF_sheen = float(line[pos:].strip())
1436 if "P BSDF Sheen Tint : " in line:
1437 pos = line.rfind(':') + 1
1438 P_BSDF_sheen_tint = float(line[pos:].strip())
1439 if "P BSDF Clearcoat :" in line:
1440 pos = line.rfind(':') + 1
1441 P_BSDF_clearcoat = float(line[pos:].strip())
1442 if "P BSDF Clearcoat Rough :" in line:
1443 pos = line.rfind(':') + 1
1444 P_BSDF_clearcoat_roughness = float(line[pos:].strip())
1445 if "P BSDF IOR :" in line:
1446 pos = line.rfind(':') + 1
1447 P_BSDF_IOR = float(line[pos:].strip())
1448 if "P BSDF Trans :" in line:
1449 pos = line.rfind(':') + 1
1450 P_BSDF_transparency = float(line[pos:].strip())
1451 if "P BSDF Trans Roughness :" in line:
1452 pos = line.rfind(':') + 1
1453 P_BSDF_transparency_roughness = float(line[pos:].strip())
1454 if "P BSDF Emisssion : " in line:
1455 pos = line.rfind(':') + 1
1456 color_value = line[pos:].strip().split(',')
1457 P_BSDF_emission = [float(color_value[0]),
1458 float(color_value[1]),
1459 float(color_value[2]),
1460 float(color_value[3])]
1461 if "P BSDF Emission Strength :" in line:
1462 pos = line.rfind(':') + 1
1463 P_BSDF_emission_strength = float(line[pos:].strip())
1464 if "P BSDF Alpha :" in line:
1465 pos = line.rfind(':') + 1
1466 P_BSDF_alpha = float(line[pos:].strip())
1468 if "Eevee Use Backface Culling :" in line:
1469 pos = line.rfind(':') + 1
1470 line = line[pos:].strip()
1471 if line.lower() in ("yes", "true", "1"):
1472 Eevee_use_backface = True
1473 else:
1474 Eevee_use_backface = False
1475 if "Eevee Blend Method :" in line:
1476 pos = line.rfind(':') + 1
1477 Eevee_blend_method = line[pos:].strip()
1478 if "Eevee Shadow Method :" in line:
1479 pos = line.rfind(':') + 1
1480 Eevee_shadow_method = line[pos:].strip()
1481 if "Eevee Clip Threshold :" in line:
1482 pos = line.rfind(':') + 1
1483 Eevee_clip_threshold = float(line[pos:].strip())
1484 if "Eevee Use Screen Refraction :" in line:
1485 pos = line.rfind(':') + 1
1486 line = line[pos:].strip()
1487 if line.lower() in ("yes", "true", "1"):
1488 Eevee_use_screen_refraction = True
1489 else:
1490 Eevee_use_screen_refraction = False
1491 if "Eevee Refraction depth : " in line:
1492 pos = line.rfind(':') + 1
1493 Eevee_refraction_depth = float(line[pos:].strip())
1494 if "Eevee Use SSS Translucency :" in line:
1495 pos = line.rfind(':') + 1
1496 line = line[pos:].strip()
1497 if line.lower() in ("yes", "true", "1"):
1498 Eevee_use_sss_translucency = True
1499 else:
1500 Eevee_use_sss_translucency = False
1501 if "Eevee Pass Index :" in line:
1502 pos = line.rfind(':') + 1
1503 Eevee_pass_index = int(line[pos:].strip())
1506 line = data_file_p.readline()
1508 list_radii = [radius_used, radius_covalent, radius_atomic]
1510 Eevee_material = EeveeProp(Eevee_use_backface,
1511 Eevee_blend_method,
1512 Eevee_shadow_method,
1513 Eevee_clip_threshold,
1514 Eevee_use_screen_refraction,
1515 Eevee_refraction_depth,
1516 Eevee_use_sss_translucency,
1517 Eevee_pass_index)
1519 P_BSDF_material = PBSDFProp(P_BSDF_subsurface_method,
1520 P_BSDF_distribution,
1521 P_BSDF_subsurface,
1522 P_BSDF_subsurface_color,
1523 P_BSDF_subsurface_radius,
1524 P_BSDF_metallic,
1525 P_BSDF_specular,
1526 P_BSDF_specular_tilt,
1527 P_BSDF_roughness,
1528 P_BSDF_anisotropic,
1529 P_BSDF_anisotropic_rotation,
1530 P_BSDF_sheen,
1531 P_BSDF_sheen_tint,
1532 P_BSDF_clearcoat,
1533 P_BSDF_clearcoat_roughness,
1534 P_BSDF_IOR,
1535 P_BSDF_transparency,
1536 P_BSDF_transparency_roughness,
1537 P_BSDF_emission,
1538 P_BSDF_emission_strength,
1539 P_BSDF_alpha)
1541 element = ElementProp(number,
1542 name,
1543 short_name,
1544 color,
1545 list_radii,
1546 list_radii_ionic,
1547 P_BSDF_material,
1548 Eevee_material)
1550 ELEMENTS.append(element)
1552 data_file_p.close()
1554 return True