1 # ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17 # ##### END GPL LICENSE BLOCK #####
22 from mathutils
import Vector
26 # -----------------------------------------------------------------------------
27 # Atom and element data
30 # This is a list that contains some data of all possible elements. The structure
33 # 1, "Hydrogen", "H", [0.0,0.0,1.0], 0.32, 0.32, 0.32 , -1 , 1.54 means
35 # No., name, short name, color, radius (used), radius (covalent), radius (atomic),
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)
42 ( 1, "Hydrogen", "H", ( 1.0, 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, 1.0), 0.93, 0.93, 0.49 ),
44 ( 3, "Lithium", "Li", ( 0.8, 0.50, 1.0, 1.0), 1.23, 1.23, 2.05 , 1 , 0.68 ),
45 ( 4, "Beryllium", "Be", ( 0.76, 1.0, 0.0, 1.0), 0.90, 0.90, 1.40 , 1 , 0.44 , 2 , 0.35 ),
46 ( 5, "Boron", "B", ( 1.0, 0.70, 0.70, 1.0), 0.82, 0.82, 1.17 , 1 , 0.35 , 3 , 0.23 ),
47 ( 6, "Carbon", "C", ( 0.56, 0.56, 0.56, 1.0), 0.77, 0.77, 0.91 , -4 , 2.60 , 4 , 0.16 ),
48 ( 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 ),
49 ( 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 ),
50 ( 9, "Fluorine", "F", ( 0.56, 0.87, 0.31, 1.0), 0.72, 0.72, 0.57 , -1 , 1.33 , 7 , 0.08 ),
51 (10, "Neon", "Ne", ( 0.70, 0.89, 0.96, 1.0), 0.71, 0.71, 0.51 , 1 , 1.12 ),
52 (11, "Sodium", "Na", ( 0.67, 0.36, 0.94, 1.0), 1.54, 1.54, 2.23 , 1 , 0.97 ),
53 (12, "Magnesium", "Mg", ( 0.54, 1.0, 0.0, 1.0), 1.36, 1.36, 1.72 , 1 , 0.82 , 2 , 0.66 ),
54 (13, "Aluminium", "Al", ( 0.74, 0.65, 0.65, 1.0), 1.18, 1.18, 1.82 , 3 , 0.51 ),
55 (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 ),
56 (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 ),
57 (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 ),
58 (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 ),
59 (18, "Argon", "Ar", ( 0.50, 0.81, 0.89, 1.0), 0.98, 0.98, 0.88 , 1 , 1.54 ),
60 (19, "Potassium", "K", ( 0.56, 0.25, 0.83, 1.0), 2.03, 2.03, 2.77 , 1 , 0.81 ),
61 (20, "Calcium", "Ca", ( 0.23, 1.0, 0.0, 1.0), 1.74, 1.74, 2.23 , 1 , 1.18 , 2 , 0.99 ),
62 (21, "Scandium", "Sc", ( 0.90, 0.90, 0.90, 1.0), 1.44, 1.44, 2.09 , 3 , 0.73 ),
63 (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 ),
64 (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 ),
65 (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 ),
66 (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 ),
67 (26, "Iron", "Fe", ( 0.87, 0.4, 0.2, 1.0), 1.17, 1.17, 1.72 , 2 , 0.74 , 3 , 0.64 ),
68 (27, "Cobalt", "Co", ( 0.94, 0.56, 0.62, 1.0), 1.16, 1.16, 1.67 , 2 , 0.72 , 3 , 0.63 ),
69 (28, "Nickel", "Ni", ( 0.31, 0.81, 0.31, 1.0), 1.15, 1.15, 1.62 , 2 , 0.69 ),
70 (29, "Copper", "Cu", ( 0.78, 0.50, 0.2, 1.0), 1.17, 1.17, 1.57 , 1 , 0.96 , 2 , 0.72 ),
71 (30, "Zinc", "Zn", ( 0.49, 0.50, 0.69, 1.0), 1.25, 1.25, 1.53 , 1 , 0.88 , 2 , 0.74 ),
72 (31, "Gallium", "Ga", ( 0.76, 0.56, 0.56, 1.0), 1.26, 1.26, 1.81 , 1 , 0.81 , 3 , 0.62 ),
73 (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 ),
74 (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 ),
75 (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 ),
76 (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 ),
77 (36, "Krypton", "Kr", ( 0.36, 0.72, 0.81, 1.0), 1.31, 1.31, 1.24 ),
78 (37, "Rubidium", "Rb", ( 0.43, 0.18, 0.69, 1.0), 2.16, 2.16, 2.98 , 1 , 1.47 ),
79 (38, "Strontium", "Sr", ( 0.0, 1.0, 0.0, 1.0), 1.91, 1.91, 2.45 , 2 , 1.12 ),
80 (39, "Yttrium", "Y", ( 0.58, 1.0, 1.0, 1.0), 1.62, 1.62, 2.27 , 3 , 0.89 ),
81 (40, "Zirconium", "Zr", ( 0.58, 0.87, 0.87, 1.0), 1.45, 1.45, 2.16 , 1 , 1.09 , 4 , 0.79 ),
82 (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 ),
83 (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 ),
84 (43, "Technetium", "Tc", ( 0.23, 0.61, 0.61, 1.0), 1.27, 1.27, 1.95 , 7 , 0.97 ),
85 (44, "Ruthenium", "Ru", ( 0.14, 0.56, 0.56, 1.0), 1.25, 1.25, 1.89 , 4 , 0.67 ),
86 (45, "Rhodium", "Rh", ( 0.03, 0.49, 0.54, 1.0), 1.25, 1.25, 1.83 , 3 , 0.68 ),
87 (46, "Palladium", "Pd", ( 0.0, 0.41, 0.52, 1.0), 1.28, 1.28, 1.79 , 2 , 0.80 , 4 , 0.65 ),
88 (47, "Silver", "Ag", ( 0.75, 0.75, 0.75, 1.0), 1.34, 1.34, 1.75 , 1 , 1.26 , 2 , 0.89 ),
89 (48, "Cadmium", "Cd", ( 1.0, 0.85, 0.56, 1.0), 1.48, 1.48, 1.71 , 1 , 1.14 , 2 , 0.97 ),
90 (49, "Indium", "In", ( 0.65, 0.45, 0.45, 1.0), 1.44, 1.44, 2.00 , 3 , 0.81 ),
91 (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 ),
92 (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 ),
93 (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 ),
94 (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 ),
95 (54, "Xenon", "Xe", ( 0.25, 0.61, 0.69, 1.0), 1.31, 1.31, 1.24 ),
96 (55, "Caesium", "Cs", ( 0.34, 0.09, 0.56, 1.0), 2.35, 2.35, 3.35 , 1 , 1.67 ),
97 (56, "Barium", "Ba", ( 0.0, 0.78, 0.0, 1.0), 1.98, 1.98, 2.78 , 1 , 1.53 , 2 , 1.34 ),
98 (57, "Lanthanum", "La", ( 0.43, 0.83, 1.0, 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.0), 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.0), 1.65, 1.65, 2.67 , 3 , 1.01 , 4 , 0.90 ),
101 (60, "Neodymium", "Nd", ( 0.78, 1.0, 0.78, 1.0), 1.64, 1.64, 2.64 , 3 , 0.99 ),
102 (61, "Promethium", "Pm", ( 0.63, 1.0, 0.78, 1.0), 1.63, 1.63, 2.62 , 3 , 0.97 ),
103 (62, "Samarium", "Sm", ( 0.56, 1.0, 0.78, 1.0), 1.62, 1.62, 2.59 , 3 , 0.96 ),
104 (63, "Europium", "Eu", ( 0.38, 1.0, 0.78, 1.0), 1.85, 1.85, 2.56 , 2 , 1.09 , 3 , 0.95 ),
105 (64, "Gadolinium", "Gd", ( 0.27, 1.0, 0.78, 1.0), 1.61, 1.61, 2.54 , 3 , 0.93 ),
106 (65, "Terbium", "Tb", ( 0.18, 1.0, 0.78, 1.0), 1.59, 1.59, 2.51 , 3 , 0.92 , 4 , 0.84 ),
107 (66, "Dysprosium", "Dy", ( 0.12, 1.0, 0.78, 1.0), 1.59, 1.59, 2.49 , 3 , 0.90 ),
108 (67, "Holmium", "Ho", ( 0.0, 1.0, 0.61, 1.0), 1.58, 1.58, 2.47 , 3 , 0.89 ),
109 (68, "Erbium", "Er", ( 0.0, 0.90, 0.45, 1.0), 1.57, 1.57, 2.45 , 3 , 0.88 ),
110 (69, "Thulium", "Tm", ( 0.0, 0.83, 0.32, 1.0), 1.56, 1.56, 2.42 , 3 , 0.87 ),
111 (70, "Ytterbium", "Yb", ( 0.0, 0.74, 0.21, 1.0), 1.74, 1.74, 2.40 , 2 , 0.93 , 3 , 0.85 ),
112 (71, "Lutetium", "Lu", ( 0.0, 0.67, 0.14, 1.0), 1.56, 1.56, 2.25 , 3 , 0.85 ),
113 (72, "Hafnium", "Hf", ( 0.30, 0.76, 1.0, 1.0), 1.44, 1.44, 2.16 , 4 , 0.78 ),
114 (73, "Tantalum", "Ta", ( 0.30, 0.65, 1.0, 1.0), 1.34, 1.34, 2.09 , 5 , 0.68 ),
115 (74, "Tungsten", "W", ( 0.12, 0.58, 0.83, 1.0), 1.30, 1.30, 2.02 , 4 , 0.70 , 6 , 0.62 ),
116 (75, "Rhenium", "Re", ( 0.14, 0.49, 0.67, 1.0), 1.28, 1.28, 1.97 , 4 , 0.72 , 7 , 0.56 ),
117 (76, "Osmium", "Os", ( 0.14, 0.4, 0.58, 1.0), 1.26, 1.26, 1.92 , 4 , 0.88 , 6 , 0.69 ),
118 (77, "Iridium", "Ir", ( 0.09, 0.32, 0.52, 1.0), 1.27, 1.27, 1.87 , 4 , 0.68 ),
119 (78, "Platinum", "Pt", ( 0.81, 0.81, 0.87, 1.0), 1.30, 1.30, 1.83 , 2 , 0.80 , 4 , 0.65 ),
120 (79, "Gold", "Au", ( 1.0, 0.81, 0.13, 1.0), 1.34, 1.34, 1.79 , 1 , 1.37 , 3 , 0.85 ),
121 (80, "Mercury", "Hg", ( 0.72, 0.72, 0.81, 1.0), 1.49, 1.49, 1.76 , 1 , 1.27 , 2 , 1.10 ),
122 (81, "Thallium", "Tl", ( 0.65, 0.32, 0.30, 1.0), 1.48, 1.48, 2.08 , 1 , 1.47 , 3 , 0.95 ),
123 (82, "Lead", "Pb", ( 0.34, 0.34, 0.38, 1.0), 1.47, 1.47, 1.81 , 2 , 1.20 , 4 , 0.84 ),
124 (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 ),
125 (84, "Polonium", "Po", ( 0.67, 0.36, 0.0, 1.0), 1.46, 1.46, 1.53 , 6 , 0.67 ),
126 (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 ),
127 (86, "Radon", "Rn", ( 0.25, 0.50, 0.58, 1.0), 1.00, 1.00, 1.34 ),
128 (87, "Francium", "Fr", ( 0.25, 0.0, 0.4, 1.0), 1.00, 1.00, 1.00 , 1 , 1.80 ),
129 (88, "Radium", "Ra", ( 0.0, 0.49, 0.0, 1.0), 1.00, 1.00, 1.00 , 2 , 1.43 ),
130 (89, "Actinium", "Ac", ( 0.43, 0.67, 0.98, 1.0), 1.00, 1.00, 1.00 , 3 , 1.18 ),
131 (90, "Thorium", "Th", ( 0.0, 0.72, 1.0, 1.0), 1.65, 1.65, 1.00 , 4 , 1.02 ),
132 (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 ),
133 (92, "Uranium", "U", ( 0.0, 0.56, 1.0, 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.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.0), 1.00, 1.00, 1.00 , 3 , 1.08 , 4 , 0.93 ),
136 (95, "Americium", "Am", ( 0.32, 0.36, 0.94, 1.0), 1.00, 1.00, 1.00 , 3 , 1.07 , 4 , 0.92 ),
137 (96, "Curium", "Cm", ( 0.47, 0.36, 0.89, 1.0), 1.00, 1.00, 1.00 ),
138 (97, "Berkelium", "Bk", ( 0.54, 0.30, 0.89, 1.0), 1.00, 1.00, 1.00 ),
139 (98, "Californium", "Cf", ( 0.63, 0.21, 0.83, 1.0), 1.00, 1.00, 1.00 ),
140 (99, "Einsteinium", "Es", ( 0.70, 0.12, 0.83, 1.0), 1.00, 1.00, 1.00 ),
141 (100, "Fermium", "Fm", ( 0.70, 0.12, 0.72, 1.0), 1.00, 1.00, 1.00 ),
142 (101, "Mendelevium", "Md", ( 0.70, 0.05, 0.65, 1.0), 1.00, 1.00, 1.00 ),
143 (102, "Nobelium", "No", ( 0.74, 0.05, 0.52, 1.0), 1.00, 1.00, 1.00 ),
144 (103, "Lawrencium", "Lr", ( 0.78, 0.0, 0.4, 1.0), 1.00, 1.00, 1.00 ),
145 (104, "Vacancy", "Vac", ( 0.5, 0.5, 0.5, 1.0), 1.00, 1.00, 1.00),
146 (105, "Default", "Default", ( 1.0, 1.0, 1.0, 1.0), 1.00, 1.00, 1.00),
147 (106, "Stick", "Stick", ( 0.5, 0.5, 0.5, 1.0), 1.00, 1.00, 1.00),
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
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
):
165 self
.short_name
= short_name
168 self
.radii_ionic
= radii_ionic
171 # This function measures the distance between two selected objects.
175 if bpy
.context
.mode
== 'EDIT_MESH':
177 atom
= bpy
.context
.edit_object
178 bm
= bmesh
.from_edit_mesh(atom
.data
)
183 locations
.append(atom
.matrix_world
@ v
.co
)
185 if len(locations
) > 1:
186 location1
= locations
[0]
187 location2
= locations
[1]
190 # In the 'OBJECT' mode
193 if len(bpy
.context
.selected_objects
) > 1:
194 location1
= bpy
.context
.selected_objects
[0].location
195 location2
= bpy
.context
.selected_objects
[1].location
199 dv
= location2
- location1
200 dist
= str(dv
.length
)
201 pos
= str.find(dist
, ".")
208 def choose_objects(action_type
,
216 # For selected objects of all selected layers
217 if who
== "ALL_IN_LAYER":
218 # Determine all selected layers.
220 for i
, layer
in enumerate(bpy
.context
.scene
.layers
):
224 # Put all objects, which are in the layers, into a list.
225 change_objects_all
= []
226 for atom
in bpy
.context
.scene
.objects
:
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
)
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).
242 for atom
in change_objects_all
:
243 if atom
.parent
!= None:
245 for atom2
in change_objects
:
246 if atom2
== atom
.parent
:
249 change_objects
.append(atom
)
251 change_objects
.append(atom
)
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
,
266 if atom
.type in {'SURFACE', 'MESH', 'META'}:
267 modify_objects(action_type
,
276 # Modifying the radius of a selected atom or stick
277 def modify_objects(action_type
,
285 # Modify atom radius (in pm)
286 if action_type
== "ATOM_RADIUS_PM" and "STICK" not in atom
.name
.upper():
287 if radius_pm
[0] in atom
.name
:
288 atom
.scale
= (radius_pm
[1]/100,) * 3
290 # Modify atom radius (all selected)
291 if action_type
== "ATOM_RADIUS_ALL" and "STICK" not in atom
.name
.upper():
292 atom
.scale
*= radius_all
294 # Modify atom radius (type, van der Waals, atomic or ionic)
295 if action_type
== "ATOM_RADIUS_TYPE" and "STICK" not in atom
.name
.upper():
296 for element
in ELEMENTS
:
297 if element
.name
in atom
.name
:
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
304 find
= (lambda searchList
, elem
:
305 [[i
for i
, x
in enumerate(searchList
) if x
== e
]
307 index
= find(charge_states
,[charge_state_chosen
])[0]
309 # Is there a charge state?
311 atom
.scale
= (charge_radii
[index
[0]],) * 3
313 # For atomic and van der Waals radii.
315 atom
.scale
= (element
.radii
[int(radius_type
)],) * 3
318 if (action_type
== "STICKS_RADIUS_ALL" and 'STICK' in atom
.name
.upper() and
319 ('CUP' in atom
.name
.upper() or
320 'CYLINDER' in atom
.name
.upper())):
322 # For dupliverts structures only: Make the cylinder or cup visible
323 # first, otherwise one cannot go into EDIT mode. Note that 'atom' here
324 # is in fact a 'stick' (cylinder or cup).
325 # First, identify if it is a normal cylinder object or a dupliverts
326 # structure. The identifier for a dupliverts structure is the parent's
327 # name, which includes "_sticks_mesh"
328 if "_sticks_mesh" in atom
.parent
.name
:
331 bpy
.context
.view_layer
.objects
.active
= atom
332 bpy
.ops
.object.mode_set(mode
='EDIT', toggle
=False)
333 bm
= bmesh
.from_edit_mesh(atom
.data
)
337 locations
.append(v
.co
)
339 center
= Vector((0.0,0.0,0.0))
340 center
= sum([location
for location
in locations
], center
)/len(locations
)
342 radius
= sum([(loc
[0]-center
[0])**2+(loc
[1]-center
[1])**2
343 for loc
in locations
], 0)
344 radius_new
= radius
* sticks_all
347 v
.co
[0] = ((v
.co
[0] - center
[0]) / radius
) * radius_new
+ center
[0]
348 v
.co
[1] = ((v
.co
[1] - center
[1]) / radius
) * radius_new
+ center
[1]
350 bpy
.ops
.object.mode_set(mode
='OBJECT', toggle
=False)
351 # Hide again the representative stick (cylinder or cup) if it is a
352 # dupliverts structure.
353 if "_sticks_mesh" in atom
.parent
.name
:
356 bpy
.context
.view_layer
.objects
.active
= None
358 # Replace atom objects
359 if action_type
== "ATOM_REPLACE_OBJ" and "STICK" not in atom
.name
.upper():
361 scn
= bpy
.context
.scene
.atom_blend
363 new_material
= draw_obj_material(scn
.replace_objs_material
,
364 atom
.active_material
)
366 # Special object (like halo, etc.)
367 if scn
.replace_objs_special
!= '0':
368 new_atom
= draw_obj_special(scn
.replace_objs_special
, atom
)
369 # Standard geometrical objects
371 # If the atom shape shall not be changed, then:
372 if scn
.replace_objs
== '0':
373 atom
.active_material
= new_material
375 # If the atom shape shall change, then:
377 new_atom
= draw_obj(scn
.replace_objs
, atom
, new_material
)
379 # Default shapes and colors for atoms
380 if action_type
== "ATOM_DEFAULT_OBJ" and "STICK" not in atom
.name
.upper():
382 scn
= bpy
.context
.scene
.atom_blend
384 # Create new material
385 new_material
= bpy
.data
.materials
.new("tmp")
386 # Create new object (NURBS sphere = '1b')
387 new_atom
= draw_obj('1b', atom
, new_material
)
388 new_atom
.active_material
= new_material
389 new_material
= draw_obj_material('0', new_material
)
391 # Change size and color of the new object
392 for element
in ELEMENTS
:
393 if element
.name
in new_atom
.name
:
394 new_atom
.scale
= (element
.radii
[0],) * 3
395 new_atom
.active_material
.diffuse_color
= element
.color
396 new_atom
.name
= element
.name
+ "_ball"
397 new_atom
.active_material
.name
= element
.name
401 # Separating atoms from a dupliverts structure.
402 def separate_atoms(scn
):
405 mesh
= bpy
.context
.edit_object
407 # Do nothing if it is not a dupliverts structure.
408 if not mesh
.instance_type
== "VERTS":
411 # This is the name of the mesh
412 mesh_name
= mesh
.name
414 coll
= mesh
.users_collection
[0]
416 # Get the coordinates of the selected vertices (atoms)
417 bm
= bmesh
.from_edit_mesh(mesh
.data
)
421 locations
.append(mesh
.matrix_world
@ v
.co
)
427 # Delete already the selected vertices
428 bpy
.ops
.mesh
.delete(type='VERT')
430 # Find the representative ball within the collection.
431 for obj
in coll
.objects
:
432 if obj
.parent
!= None:
433 if obj
.parent
.name
== mesh_name
:
436 # Create balls and put them at the places where the vertices (atoms) have
438 for location
in locations
:
439 obj_dupli
= obj
.copy()
440 obj_dupli
.data
= obj
.data
.copy()
441 obj_dupli
.parent
= None
442 coll
.objects
.link(obj_dupli
)
443 obj_dupli
.location
= location
444 obj_dupli
.name
= obj
.name
+ "_sep"
445 # Do not hide the object!
446 obj_dupli
.hide_set(False)
449 bpy
.ops
.object.mode_set(mode
='OBJECT', toggle
=False)
450 bpy
.context
.view_layer
.objects
.active
= mesh
453 # Prepare a new material
454 def draw_obj_material(material_type
, material
):
456 if material_type
== '0': # Unchanged
457 material_new
= material
458 if material_type
== '1': # Normal
459 material_new
= bpy
.data
.materials
.new(material
.name
+ "_normal")
460 if material_type
== '2': # Transparent
461 material_new
= bpy
.data
.materials
.new(material
.name
+ "_transparent")
462 material_new
.metallic
= 0.8
463 material_new
.specular_intensity
= 0.5
464 material_new
.roughness
= 0.3
465 material_new
.blend_method
= 'OPAQUE'
466 material_new
.show_transparent_back
= False
467 # Some properties for cycles
468 material_new
.use_nodes
= True
469 mat_P_BSDF
= material_new
.node_tree
.nodes
['Principled BSDF']
470 mat_P_BSDF
.inputs
['Metallic'].default_value
= 0.1
471 mat_P_BSDF
.inputs
['Roughness'].default_value
= 0.2
472 mat_P_BSDF
.inputs
['Transmission'].default_value
= 0.9
473 mat_P_BSDF
.inputs
['IOR'].default_value
= 0.8
474 if material_type
== '3': # Reflecting
475 material_new
= bpy
.data
.materials
.new(material
.name
+ "_reflecting")
476 material_new
.metallic
= 0.5
477 material_new
.specular_intensity
= 0.5
478 material_new
.roughness
= 0.0
479 material_new
.blend_method
= 'OPAQUE'
480 # Some properties for cycles
481 material_new
.use_nodes
= True
482 mat_P_BSDF
= material_new
.node_tree
.nodes
['Principled BSDF']
483 mat_P_BSDF
.inputs
['Metallic'].default_value
= 0.95
484 mat_P_BSDF
.inputs
['Roughness'].default_value
= 0.1
485 mat_P_BSDF
.inputs
['Transmission'].default_value
= 0.0
486 mat_P_BSDF
.inputs
['IOR'].default_value
= 1.0
487 if material_type
== '4': # Transparent + reflecting
488 material_new
= bpy
.data
.materials
.new(material
.name
+ "_trans+refl")
489 material_new
.metallic
= 0.3
490 material_new
.specular_intensity
= 0.5
491 material_new
.roughness
= 0.3
492 material_new
.blend_method
= 'OPAQUE'
493 material_new
.show_transparent_back
= False
494 # Some properties for cycles
495 material_new
.use_nodes
= True
496 mat_P_BSDF
= material_new
.node_tree
.nodes
['Principled BSDF']
497 mat_P_BSDF
.inputs
['Metallic'].default_value
= 0.5
498 mat_P_BSDF
.inputs
['Roughness'].default_value
= 0.2
499 mat_P_BSDF
.inputs
['Transmission'].default_value
= 0.5
500 mat_P_BSDF
.inputs
['IOR'].default_value
= 0.8
502 # Always, when the material is changed, a new name is created. Note that
503 # this makes sense: Imagine, an other object uses the same material as the
504 # selected one. After changing the material of the selected object the old
505 # material should certainly not change and remain the same.
506 if material_type
in {'1','2','3','4'}:
507 if "_repl" in material
.name
:
508 pos
= material
.name
.rfind("_repl")
509 if material
.name
[pos
+5:].isdigit():
510 counter
= int(material
.name
[pos
+5:])
511 material_new
.name
= material
.name
[:pos
]+"_repl"+str(counter
+1)
513 material_new
.name
= material
.name
+"_repl1"
515 material_new
.name
= material
.name
+"_repl1"
516 material_new
.diffuse_color
= material
.diffuse_color
521 # Get the collection of an object.
522 def get_collection_object(obj
):
524 coll_all
= obj
.users_collection
525 if len(coll_all
) > 0:
528 coll
= bpy
.context
.scene
.collection
533 # Draw an object (e.g. cube, sphere, cylinder, ...)
534 def draw_obj(atom_shape
, atom
, new_material
):
537 if atom_shape
== '0':
540 if atom_shape
== '1a': #Sphere mesh
541 bpy
.ops
.mesh
.primitive_uv_sphere_add(
546 enter_editmode
=False,
547 location
=atom
.location
,
549 if atom_shape
== '1b': #Sphere NURBS
550 bpy
.ops
.surface
.primitive_nurbs_surface_sphere_add(
552 enter_editmode
=False,
553 location
=atom
.location
,
554 rotation
=(0.0, 0.0, 0.0))
555 if atom_shape
== '2': #Cube
556 bpy
.ops
.mesh
.primitive_cube_add(
558 enter_editmode
=False,
559 location
=atom
.location
,
560 rotation
=(0.0, 0.0, 0.0))
561 if atom_shape
== '3': #Plane
562 bpy
.ops
.mesh
.primitive_plane_add(
564 enter_editmode
=False,
565 location
=atom
.location
,
566 rotation
=(0.0, 0.0, 0.0))
567 if atom_shape
== '4a': #Circle
568 bpy
.ops
.mesh
.primitive_circle_add(
573 enter_editmode
=False,
574 location
=atom
.location
,
576 if atom_shape
== '4b': #Circle NURBS
577 bpy
.ops
.surface
.primitive_nurbs_surface_circle_add(
579 enter_editmode
=False,
580 location
=atom
.location
,
582 if atom_shape
in {'5a','5b','5c','5d','5e'}: #Icosphere
583 index
= {'5a':1,'5b':2,'5c':3,'5d':4,'5e':5}
584 bpy
.ops
.mesh
.primitive_ico_sphere_add(
585 subdivisions
=int(index
[atom_shape
]),
588 enter_editmode
=False,
589 location
=atom
.location
,
591 if atom_shape
== '6a': #Cylinder
592 bpy
.ops
.mesh
.primitive_cylinder_add(
596 end_fill_type
='NGON',
598 enter_editmode
=False,
599 location
=atom
.location
,
601 if atom_shape
== '6b': #Cylinder NURBS
602 bpy
.ops
.surface
.primitive_nurbs_surface_cylinder_add(
604 enter_editmode
=False,
605 location
=atom
.location
,
607 if atom_shape
== '7': #Cone
608 bpy
.ops
.mesh
.primitive_cone_add(
613 end_fill_type
='NGON',
615 enter_editmode
=False,
616 location
=atom
.location
,
618 if atom_shape
== '8a': #Torus
619 bpy
.ops
.mesh
.primitive_torus_add(
621 location
=atom
.location
,
629 if atom_shape
== '8b': #Torus NURBS
630 bpy
.ops
.surface
.primitive_nurbs_surface_torus_add(
632 enter_editmode
=False,
633 location
=atom
.location
,
636 new_atom
= bpy
.context
.view_layer
.objects
.active
637 new_atom
.scale
= atom
.scale
+ Vector((0.0,0.0,0.0))
638 new_atom
.name
= atom
.name
639 new_atom
.select_set(True)
641 new_atom
.active_material
= new_material
643 # If it is the representative object of a duplivert structure then
644 # transfer the parent and hide the new object.
645 if atom
.parent
!= None:
646 new_atom
.parent
= atom
.parent
647 new_atom
.hide_set(True)
649 # Note the collection where the old object was placed into.
650 coll_old_atom
= get_collection_object(atom
)
652 # Note the collection where the new object was placed into.
653 coll_new_atom_past
= get_collection_object(new_atom
)
655 # If it is not the same collection then ...
656 if coll_new_atom_past
!= coll_old_atom
:
657 # Put the new object into the collection of the old object and ...
658 coll_old_atom
.objects
.link(new_atom
)
659 # ... unlink the new atom from its original collection.
660 coll_new_atom_past
.objects
.unlink(new_atom
)
662 # If necessary, remove the childrens of the old object.
663 for child
in atom
.children
:
664 bpy
.ops
.object.select_all(action
='DESELECT')
666 child
.select_set(True)
668 coll_child
= get_collection_object(child
)
669 coll_child
.objects
.unlink(child
)
670 bpy
.ops
.object.delete()
673 # Deselect everything
674 bpy
.ops
.object.select_all(action
='DESELECT')
675 # Make the old atom visible.
677 # Select the old atom.
678 atom
.select_set(True)
679 # Remove the parent if necessary.
681 # Unlink the old object from the collection.
682 coll_old_atom
.objects
.unlink(atom
)
683 # Delete the old atom
684 bpy
.ops
.object.delete()
687 #if "_F2+_center" or "_F+_center" or "_F0_center" in coll_old_atom:
688 # print("Delete the collection")
693 # Draw a special object (e.g. halo, etc. ...)
694 def draw_obj_special(atom_shape
, atom
):
696 # Note the collection where 'atom' is placed into.
697 coll_atom
= get_collection_object(atom
)
699 # Now, create a collection for the new objects
701 # Create the new collection and ...
702 coll_new
= bpy
.data
.collections
.new(coll_new
)
703 # ... link it to the collection, which contains 'atom'.
704 coll_atom
.children
.link(coll_new
)
708 if atom_shape
== '1':
709 # Create first a cube
710 bpy
.ops
.mesh
.primitive_cube_add(align
='WORLD',
711 enter_editmode
=False,
712 location
=atom
.location
,
713 rotation
=(0.0, 0.0, 0.0))
714 cube
= bpy
.context
.view_layer
.objects
.active
715 cube
.scale
= atom
.scale
+ Vector((0.0,0.0,0.0))
716 cube
.name
= atom
.name
+ "_F2+_vac"
717 cube
.select_set(True)
718 # New material for this cube
719 material_cube
= bpy
.data
.materials
.new(atom
.name
+ "_F2+_vac")
720 material_cube
.diffuse_color
= [0.8, 0.0, 0.0, 1.0]
721 material_cube
.metallic
= 0.8
722 material_cube
.specular_intensity
= 0.5
723 material_cube
.roughness
= 0.3
724 material_cube
.blend_method
= 'OPAQUE'
725 material_cube
.show_transparent_back
= True
726 # Some properties for cycles
727 material_cube
.use_nodes
= True
728 mat_P_BSDF
= material_cube
.node_tree
.nodes
['Principled BSDF']
729 mat_P_BSDF
.inputs
['Metallic'].default_value
= 0.1
730 mat_P_BSDF
.inputs
['Roughness'].default_value
= 0.2
731 mat_P_BSDF
.inputs
['Transmission'].default_value
= 0.9
732 mat_P_BSDF
.inputs
['IOR'].default_value
= 0.8
733 cube
.active_material
= material_cube
734 # Put a nice point lamp inside the defect
735 lamp_data
= bpy
.data
.lights
.new(name
=atom
.name
+ "_F2+_lamp",
737 lamp_data
.distance
= atom
.scale
[0] * 2.0
738 lamp_data
.energy
= 1.0
739 lamp_data
.color
= (0.8, 0.8, 0.8)
740 lamp
= bpy
.data
.objects
.new(atom
.name
+ "_F2+_lamp", lamp_data
)
741 lamp
.location
= Vector((0.0, 0.0, 0.0))
742 bpy
.context
.collection
.objects
.link(lamp
)
744 # Some properties for cycles
745 lamp
.data
.use_nodes
= True
746 lmp_P_BSDF
= lamp
.data
.node_tree
.nodes
['Emission']
747 lmp_P_BSDF
.inputs
['Strength'].default_value
= 2000
748 # The new 'atom' is the F2+ defect
751 # Note the collection where all the new objects were placed into.
752 # We use only one object, the cube
753 coll_ori
= get_collection_object(cube
)
755 # If it is not the same collection then ...
756 if coll_ori
!= coll_new
:
757 # Put all new objects into the new collection and ...
758 coll_new
.objects
.link(cube
)
759 coll_new
.objects
.link(lamp
)
760 # ... unlink them from their original collection.
761 coll_ori
.objects
.unlink(cube
)
762 coll_ori
.objects
.unlink(lamp
)
764 coll_new
.name
= atom
.name
+ "_F2+_center"
766 if atom
.parent
!= None:
767 cube
.parent
= atom
.parent
772 if atom_shape
== '2':
773 # Create first a cube
774 bpy
.ops
.mesh
.primitive_cube_add(align
='WORLD',
775 enter_editmode
=False,
776 location
=atom
.location
,
777 rotation
=(0.0, 0.0, 0.0))
778 cube
= bpy
.context
.view_layer
.objects
.active
779 cube
.scale
= atom
.scale
+ Vector((0.0,0.0,0.0))
780 cube
.name
= atom
.name
+ "_F+_vac"
781 cube
.select_set(True)
782 # New material for this cube
783 material_cube
= bpy
.data
.materials
.new(atom
.name
+ "_F+_vac")
784 material_cube
.diffuse_color
= [0.0, 0.0, 0.8, 1.0]
785 material_cube
.metallic
= 0.8
786 material_cube
.specular_intensity
= 0.5
787 material_cube
.roughness
= 0.3
788 material_cube
.blend_method
= 'OPAQUE'
789 material_cube
.show_transparent_back
= True
790 # Some properties for cycles
791 material_cube
.use_nodes
= True
792 mat_P_BSDF
= material_cube
.node_tree
.nodes
['Principled BSDF']
793 mat_P_BSDF
.inputs
['Metallic'].default_value
= 0.1
794 mat_P_BSDF
.inputs
['Roughness'].default_value
= 0.2
795 mat_P_BSDF
.inputs
['Transmission'].default_value
= 0.9
796 mat_P_BSDF
.inputs
['IOR'].default_value
= 0.8
797 cube
.active_material
= material_cube
798 # Create now an electron
799 scale
= atom
.scale
/ 10.0
800 bpy
.ops
.surface
.primitive_nurbs_surface_sphere_add(
802 enter_editmode
=False,
803 location
=(0.0, 0.0, 0.0),
804 rotation
=(0.0, 0.0, 0.0))
805 electron
= bpy
.context
.view_layer
.objects
.active
806 electron
.scale
= scale
807 electron
.name
= atom
.name
+ "_F+_electron"
808 electron
.parent
= cube
809 # New material for the electron
810 material_electron
= bpy
.data
.materials
.new(atom
.name
+ "_F+-center")
811 material_electron
.diffuse_color
= [0.0, 0.0, 0.8, 1.0]
812 material_electron
.metallic
= 0.8
813 material_electron
.specular_intensity
= 0.5
814 material_electron
.roughness
= 0.3
815 material_electron
.blend_method
= 'OPAQUE'
816 material_electron
.show_transparent_back
= False
817 electron
.active_material
= material_electron
818 # Put a nice point lamp inside the electron
819 lamp_data
= bpy
.data
.lights
.new(name
=atom
.name
+ "_F+_lamp",
821 lamp_data
.distance
= atom
.scale
[0] * 2.0
822 lamp_data
.energy
= 1.0
823 lamp_data
.color
= (0.8, 0.8, 0.8)
824 lamp
= bpy
.data
.objects
.new(atom
.name
+ "_F+_lamp", lamp_data
)
825 lamp
.location
= Vector((scale
[0]*1.5, 0.0, 0.0))
826 bpy
.context
.collection
.objects
.link(lamp
)
828 # Some properties for cycles
829 lamp
.data
.use_nodes
= True
830 lmp_P_BSDF
= lamp
.data
.node_tree
.nodes
['Emission']
831 lmp_P_BSDF
.inputs
['Strength'].default_value
= 2000
832 # The new 'atom' is the F+ defect complex + lamp
835 # Note the collection where all the new objects were placed into.
836 # We use only one object, the cube
837 coll_ori
= get_collection_object(cube
)
839 # If it is not the same collection then ...
840 if coll_ori
!= coll_new
:
841 # Put all new objects into the new collection and ...
842 coll_new
.objects
.link(cube
)
843 coll_new
.objects
.link(electron
)
844 coll_new
.objects
.link(lamp
)
845 # ... unlink them from their original collection.
846 coll_ori
.objects
.unlink(cube
)
847 coll_ori
.objects
.unlink(electron
)
848 coll_ori
.objects
.unlink(lamp
)
850 coll_new
.name
= atom
.name
+ "_F+_center"
852 if atom
.parent
!= None:
853 cube
.parent
= atom
.parent
855 electron
.hide_set(True)
859 if atom_shape
== '3':
860 # Create first a cube
861 bpy
.ops
.mesh
.primitive_cube_add(align
='WORLD',
862 enter_editmode
=False,
863 location
=atom
.location
,
864 rotation
=(0.0, 0.0, 0.0))
865 cube
= bpy
.context
.view_layer
.objects
.active
866 cube
.scale
= atom
.scale
+ Vector((0.0,0.0,0.0))
867 cube
.name
= atom
.name
+ "_F0_vac"
868 cube
.select_set(True)
869 # New material for this cube
870 material_cube
= bpy
.data
.materials
.new(atom
.name
+ "_F0_vac")
871 material_cube
.diffuse_color
= [0.8, 0.8, 0.8, 1.0]
872 material_cube
.metallic
= 0.8
873 material_cube
.specular_intensity
= 0.5
874 material_cube
.roughness
= 0.83
875 material_cube
.blend_method
= 'OPAQUE'
876 material_cube
.show_transparent_back
= True
877 # Some properties for cycles
878 material_cube
.use_nodes
= True
879 mat_P_BSDF
= material_cube
.node_tree
.nodes
['Principled BSDF']
880 mat_P_BSDF
.inputs
['Metallic'].default_value
= 0.1
881 mat_P_BSDF
.inputs
['Roughness'].default_value
= 0.2
882 mat_P_BSDF
.inputs
['Transmission'].default_value
= 0.9
883 mat_P_BSDF
.inputs
['IOR'].default_value
= 0.8
884 cube
.active_material
= material_cube
885 # Create now two electrons
886 scale
= atom
.scale
/ 10.0
887 bpy
.ops
.surface
.primitive_nurbs_surface_sphere_add(
889 enter_editmode
=False,
890 location
=(scale
[0]*1.5,0.0,0.0),
891 rotation
=(0.0, 0.0, 0.0))
892 electron1
= bpy
.context
.view_layer
.objects
.active
893 electron1
.scale
= scale
894 electron1
.name
= atom
.name
+ "_F0_electron1"
895 electron1
.parent
= cube
896 bpy
.ops
.surface
.primitive_nurbs_surface_sphere_add(
898 enter_editmode
=False,
899 location
=(-scale
[0]*1.5,0.0,0.0),
900 rotation
=(0.0, 0.0, 0.0))
901 electron2
= bpy
.context
.view_layer
.objects
.active
902 electron2
.scale
= scale
903 electron2
.name
= atom
.name
+ "_F0_electron2"
904 electron2
.parent
= cube
905 # New material for the electrons
906 material_electron
= bpy
.data
.materials
.new(atom
.name
+ "_F0-center")
907 material_electron
.diffuse_color
= [0.0, 0.0, 0.8, 1.0]
908 material_electron
.metallic
= 0.8
909 material_electron
.specular_intensity
= 0.5
910 material_electron
.roughness
= 0.3
911 material_electron
.blend_method
= 'OPAQUE'
912 material_electron
.show_transparent_back
= False
913 electron1
.active_material
= material_electron
914 electron2
.active_material
= material_electron
915 # Put two nice point lamps inside the electrons
916 lamp1_data
= bpy
.data
.lights
.new(name
=atom
.name
+ "_F0_lamp1",
918 lamp1_data
.distance
= atom
.scale
[0] * 2.0
919 lamp1_data
.energy
= 1.0
920 lamp1_data
.color
= (0.8, 0.8, 0.8)
921 lamp1
= bpy
.data
.objects
.new(atom
.name
+ "_F0_lamp", lamp1_data
)
922 lamp1
.location
= Vector((scale
[0]*1.5, 0.0, 0.0))
923 bpy
.context
.collection
.objects
.link(lamp1
)
925 lamp2_data
= bpy
.data
.lights
.new(name
=atom
.name
+ "_F0_lamp2",
927 lamp2_data
.distance
= atom
.scale
[0] * 2.0
928 lamp2_data
.energy
= 1.0
929 lamp2_data
.color
= (0.8, 0.8, 0.8)
930 lamp2
= bpy
.data
.objects
.new(atom
.name
+ "_F0_lamp", lamp2_data
)
931 lamp2
.location
= Vector((-scale
[0]*1.5, 0.0, 0.0))
932 bpy
.context
.collection
.objects
.link(lamp2
)
934 # Some properties for cycles
935 lamp1
.data
.use_nodes
= True
936 lamp2
.data
.use_nodes
= True
937 lmp1_P_BSDF
= lamp1
.data
.node_tree
.nodes
['Emission']
938 lmp2_P_BSDF
= lamp1
.data
.node_tree
.nodes
['Emission']
939 lmp1_P_BSDF
.inputs
['Strength'].default_value
= 200
940 lmp2_P_BSDF
.inputs
['Strength'].default_value
= 200
941 # The new 'atom' is the F0 defect complex + lamps
944 # Note the collection where all the new objects were placed into.
945 # We use only one object, the cube
946 coll_ori
= get_collection_object(cube
)
948 # If it is not the same collection then ...
949 if coll_ori
!= coll_new
:
950 # Put all new objects into the collection of 'atom' and ...
951 coll_new
.objects
.link(cube
)
952 coll_new
.objects
.link(electron1
)
953 coll_new
.objects
.link(electron2
)
954 coll_new
.objects
.link(lamp1
)
955 coll_new
.objects
.link(lamp2
)
956 # ... unlink them from their original collection.
957 coll_ori
.objects
.unlink(cube
)
958 coll_ori
.objects
.unlink(electron1
)
959 coll_ori
.objects
.unlink(electron2
)
960 coll_ori
.objects
.unlink(lamp1
)
961 coll_ori
.objects
.unlink(lamp2
)
963 coll_new
.name
= atom
.name
+ "_F0_center"
965 if atom
.parent
!= None:
966 cube
.parent
= atom
.parent
968 electron1
.hide_set(True)
969 electron2
.hide_set(True)
973 # Deselect everything
974 bpy
.ops
.object.select_all(action
='DESELECT')
975 # Make the old atom visible.
977 # Select the old atom.
978 atom
.select_set(True)
979 # Remove the parent if necessary.
981 # Unlink the old object from the collection.
982 coll_atom
.objects
.unlink(atom
)
983 # Delete the old atom
984 bpy
.ops
.object.delete()
990 # Initialization of the list 'ELEMENTS'.
995 for item
in ELEMENTS_DEFAULT
:
997 # All three radii into a list
998 radii
= [item
[4],item
[5],item
[6]]
999 # The handling of the ionic radii will be done later. So far, it is an
1001 radii_ionic
= item
[7:]
1003 li
= ElementProp(item
[0],item
[1],item
[2],item
[3],
1008 # Custom data file: changing color and radii by using the list 'ELEMENTS'.
1009 def custom_datafile_change_atom_props():
1011 for atom
in bpy
.context
.selected_objects
:
1012 if len(atom
.children
) != 0:
1013 child
= atom
.children
[0]
1014 if child
.type in {'SURFACE', 'MESH', 'META'}:
1015 for element
in ELEMENTS
:
1016 if element
.name
in atom
.name
:
1017 child
.scale
= (element
.radii
[0],) * 3
1018 child
.active_material
.diffuse_color
= element
.color
1020 if atom
.type in {'SURFACE', 'MESH', 'META'}:
1021 for element
in ELEMENTS
:
1022 if element
.name
in atom
.name
:
1023 atom
.scale
= (element
.radii
[0],) * 3
1024 atom
.active_material
.diffuse_color
= element
.color
1027 # Reading a custom data file and modifying the list 'ELEMENTS'.
1028 def custom_datafile(path_datafile
):
1030 if path_datafile
== "":
1033 path_datafile
= bpy
.path
.abspath(path_datafile
)
1035 if os
.path
.isfile(path_datafile
) == False:
1038 # The whole list gets deleted! We build it new.
1041 # Read the data file, which contains all data
1042 # (atom name, radii, colors, etc.)
1043 data_file_p
= open(path_datafile
, "r")
1045 for line
in data_file_p
:
1049 line
= data_file_p
.readline()
1051 line
= data_file_p
.readline()
1052 number
= line
[19:-1]
1054 line
= data_file_p
.readline()
1057 line
= data_file_p
.readline()
1058 short_name
= line
[19:-1]
1060 line
= data_file_p
.readline()
1061 color_value
= line
[19:-1].split(',')
1062 color
= [float(color_value
[0]),
1063 float(color_value
[1]),
1064 float(color_value
[2]),
1065 float(color_value
[3])]
1067 line
= data_file_p
.readline()
1068 radius_used
= float(line
[19:-1])
1070 line
= data_file_p
.readline()
1071 radius_atomic
= float(line
[19:-1])
1072 # Van der Waals radius
1073 line
= data_file_p
.readline()
1074 radius_vdW
= float(line
[19:-1])
1075 radii
= [radius_used
,radius_atomic
,radius_vdW
]
1078 element
= ElementProp(number
,name
,short_name
,color
,
1081 ELEMENTS
.append(element
)