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 #####
20 from bpy
.types
import Operator
, Panel
21 from bpy
.props
import (StringProperty
,
26 from io_mesh_atomic
.utility_panel
import choose_objects
27 from io_mesh_atomic
.utility_panel
import custom_datafile
28 from io_mesh_atomic
.utility_panel
import custom_datafile_change_atom_props
29 from io_mesh_atomic
.utility_panel
import separate_atoms
30 from io_mesh_atomic
.utility_panel
import distance
33 # -----------------------------------------------------------------------------
37 class PANEL_PT_prepare(Panel
):
38 bl_label
= "Atomic Blender Utilities"
39 bl_space_type
= "VIEW_3D"
41 bl_options
= {'DEFAULT_CLOSED'}
42 bl_category
= "Create"
43 bl_idname
= "ATOMIC_PT_utilities"
46 # This thing here just guarantees that the panel is NOT opened when the
47 # check box in the addon preferences is not activated! See __init__.py
49 def poll(cls
, context
):
50 pref
= context
.preferences
51 return pref
.addons
[__package__
].preferences
.bool_utility
53 def draw(self
, context
):
55 scn
= context
.scene
.atom_blend
58 col
= box
.column(align
=True)
59 col
.label(text
="Custom data file")
60 col
.prop(scn
, "datafile")
61 col
.operator("atom_blend.datafile_apply")
64 col
= box
.column(align
=True)
65 col
.label(text
="Measure distances")
66 col
.operator("atom_blend.button_distance")
67 col
.prop(scn
, "distance")
69 # This is from Blender 2.79 and does not work in 2.80. However, it
70 # might be useful later on if changed.
73 #col = box.column(align=True)
74 #col.label(text="All changes concern:")
75 #col.prop(scn, "action_type")
78 col
= box
.column(align
=True)
79 col
.label(text
="Change atom size")
80 col
.label(text
="1. Type of radii")
81 col
.prop(scn
, "radius_type")
83 col2
.active
= (scn
.radius_type
== '3')
84 col2
.prop(scn
, "radius_type_ionic")
85 col
= box
.column(align
=True)
86 col
.label(text
="2. Radii in pm")
87 col
.prop(scn
, "radius_pm_name")
88 col
.prop(scn
, "radius_pm")
89 col
= box
.column(align
=True)
90 col
.label(text
="3. Radii by scale")
91 col
.prop(scn
, "radius_all")
93 row
.operator("atom_blend.radius_all_smaller")
94 row
.operator("atom_blend.radius_all_bigger")
97 col
= box
.column(align
=True)
98 col
.label(text
="Change stick size")
99 col
.prop(scn
, "sticks_all")
101 row
.operator("atom_blend.sticks_all_smaller")
102 row
.operator("atom_blend.sticks_all_bigger")
105 col
= box
.column(align
=True)
106 col
.label(text
="Change atom shape")
108 col2
.active
= (scn
.replace_objs_special
== '0')
109 col2
.prop(scn
, "replace_objs")
110 col2
.prop(scn
, "replace_objs_material")
111 col
.prop(scn
, "replace_objs_special")
112 col
.operator("atom_blend.replace_atom")
113 col
.label(text
="Default values")
114 col
.operator("atom_blend.default_atoms")
117 col
= box
.column(align
=True)
118 col
.label(text
="Separate atoms")
120 col3
.active
= (bpy
.context
.mode
== 'EDIT_MESH')
121 col3
.operator("atom_blend.separate_atom")
124 # The properties of buttons etc. in the panel.
125 class PanelProperties(bpy
.types
.PropertyGroup
):
127 def Callback_radius_type(self
, context
):
128 scn
= bpy
.context
.scene
.atom_blend
129 choose_objects("ATOM_RADIUS_TYPE",
134 scn
.radius_type_ionic
,
136 def Callback_radius_pm(self
, context
):
137 scn
= bpy
.context
.scene
.atom_blend
138 choose_objects("ATOM_RADIUS_PM",
147 datafile
: StringProperty(
148 name
= "", description
="Path to your custom data file",
149 maxlen
= 256, default
= "", subtype
='FILE_PATH')
150 XYZ_file
: StringProperty(
151 name
= "Path to file", default
="",
152 description
= "Path of the XYZ file")
153 number_atoms
: StringProperty(name
="",
154 default
="Number", description
= "This output shows "
155 "the number of atoms which have been loaded")
156 distance
: StringProperty(
157 name
="", default
="Distance (A)",
158 description
="Distance of 2 objects in Angstrom")
159 replace_objs
: EnumProperty(
161 description
="Choose a different atom shape.",
162 items
=(('0',"Unchanged", "Do not change the shape"),
163 ('1a',"Sphere (Mesh)", "Replace with a sphere (Mesh)"),
164 ('1b',"Sphere (NURBS)", "Replace with a sphere (NURBS)"),
165 ('2',"Cube", "Replace with a cube"),
166 ('3',"Plane", "Replace with a plane"),
167 ('4a',"Circle (Mesh)", "Replace with a circle (Mesh)"),
168 ('4b',"Circle (NURBS)", "Replace with a circle (NURBS)"),
169 ('5a',"Icosphere 1", "Replace with a icosphere, subd=1"),
170 ('5b',"Icosphere 2", "Replace with a icosphere, subd=2"),
171 ('5c',"Icosphere 3", "Replace with a icosphere, subd=3"),
172 ('5d',"Icosphere 4", "Replace with a icosphere, subd=4"),
173 ('5e',"Icosphere 5", "Replace with a icosphere, subd=5"),
174 ('6a',"Cylinder (Mesh)", "Replace with a cylinder (Mesh)"),
175 ('6b',"Cylinder (NURBS)", "Replace with a cylinder (NURBS)"),
176 ('7',"Cone", "Replace with a cone"),
177 ('8a',"Torus (Mesh)", "Replace with a torus (Mesh)"),
178 ('8b',"Torus (NURBS)", "Replace with a torus (NURBS)")),
180 replace_objs_material
: EnumProperty(
182 description
="Choose a different material.",
183 items
=(('0',"Unchanged", "Leave the material unchanged"),
184 ('1',"Normal", "Use normal material (no transparency and reflection)"),
185 ('2',"Transparent", "Use transparent material"),
186 ('3',"Reflecting", "Use reflecting material"),
187 ('4',"Transparent + reflecting", "Use transparent and reflecting material")),
189 replace_objs_special
: EnumProperty(
191 description
="Choose a special atom shape.",
192 items
=(('0',"None", "Use no special shape."),
193 ('1',"F2+ center", "Replace with a F2+ center"),
194 ('2',"F+ center", "Replace with a F+ center"),
195 ('3',"F0 center", "Replace with a F0 center")),
197 action_type
: EnumProperty(
199 description
="Which objects shall be modified?",
200 items
=(('ALL_ACTIVE',"all active objects", "in the current layer"),
201 ('ALL_IN_LAYER',"all in all selected layers",
202 "in selected layer(s)")),
203 default
='ALL_ACTIVE',)
204 radius_type
: EnumProperty(
206 description
="Which type of atom radii?",
207 items
=(('0',"predefined", "Use pre-defined radii"),
208 ('1',"atomic", "Use atomic radii"),
209 ('2',"van der Waals","Use van der Waals radii"),
210 ('3',"ionic radii", "Use ionic radii")),
211 default
='0',update
=Callback_radius_type
)
212 radius_type_ionic
: EnumProperty(
214 description
="Charge state of the ions if existing.",
215 items
=(('0',"-4", "Charge state -4"),
216 ('1',"-3", "Charge state -3"),
217 ('2',"-2", "Charge state -2"),
218 ('3',"-1", "Charge state -1"),
219 ('4'," 0", "Charge state 0: nothing is done"),
220 ('5',"+1", "Charge state +1"),
221 ('6',"+2", "Charge state +2"),
222 ('7',"+3", "Charge state +3"),
223 ('8',"+4", "Charge state +4"),
224 ('9',"+5", "Charge state +5"),
225 ('10',"+6", "Charge state +6"),
226 ('11',"+7", "Charge state +7")),
227 default
='4',update
=Callback_radius_type
)
228 radius_pm_name
: StringProperty(
229 name
="", default
="Atom name",
230 description
="Put in the name of the atom (e.g. Hydrogen)")
231 radius_pm
: FloatProperty(
232 name
="", default
=100.0, min=0.0,
233 description
="Put in the radius of the atom (in pm)",
234 update
=Callback_radius_pm
)
235 radius_all
: FloatProperty(
236 name
="Scale", default
= 1.05, min=1.0, max=5.0,
237 description
="Put in the scale factor")
238 sticks_all
: FloatProperty(
239 name
="Scale", default
= 1.05, min=1.0, max=5.0,
240 description
="Put in the scale factor")
243 # Button loading a custom data file
244 class DatafileApply(Operator
):
245 bl_idname
= "atom_blend.datafile_apply"
247 bl_description
= "Use color and radii values stored in the custom file"
249 def execute(self
, context
):
250 scn
= bpy
.context
.scene
.atom_blend
252 if scn
.datafile
== "":
255 custom_datafile(scn
.datafile
)
256 custom_datafile_change_atom_props()
261 # Button for separating single atoms from a dupliverts structure
262 class DefaultAtom(Operator
):
263 bl_idname
= "atom_blend.default_atoms"
265 bl_description
= ("Use default shapes and colors for atoms.")
267 # Are we in the OBJECT mode?
269 def poll(self
, context
):
270 if bpy
.context
.mode
== 'OBJECT':
275 def execute(self
, context
):
276 scn
= bpy
.context
.scene
.atom_blend
277 choose_objects("ATOM_DEFAULT_OBJ",
287 # Button for separating single atoms from a dupliverts structure
288 class ReplaceAtom(Operator
):
289 bl_idname
= "atom_blend.replace_atom"
291 bl_description
= ("Replace selected atoms with atoms of different shape.")
293 # Are we in the OBJECT mode?
295 def poll(self
, context
):
296 if bpy
.context
.mode
== 'OBJECT':
301 def execute(self
, context
):
302 scn
= bpy
.context
.scene
.atom_blend
303 choose_objects("ATOM_REPLACE_OBJ",
313 # Button for separating single atoms from a dupliverts structure
314 class SeparateAtom(Operator
):
315 bl_idname
= "atom_blend.separate_atom"
316 bl_label
= "Separate"
317 bl_description
= ("Separate selected atoms in a dupliverts structure. "
318 "You have to be in the 'Edit Mode'")
320 # Are we in the EDIT mode?
322 def poll(self
, context
):
323 if bpy
.context
.mode
== 'EDIT_MESH':
328 def execute(self
, context
):
329 scn
= bpy
.context
.scene
.atom_blend
336 # Button for measuring the distance of active objects
337 class DistanceButton(Operator
):
338 bl_idname
= "atom_blend.button_distance"
339 bl_label
= "Measure ..."
340 bl_description
= "Measure the distance between two atoms (objects)."
342 def execute(self
, context
):
343 scn
= bpy
.context
.scene
.atom_blend
346 # Put the distance into the string of the output field.
351 # Button for increasing the radii of all selected atoms
352 class RadiusAllBiggerButton(Operator
):
353 bl_idname
= "atom_blend.radius_all_bigger"
354 bl_label
= "Bigger ..."
355 bl_description
= "Increase the radii of selected atoms"
357 def execute(self
, context
):
358 scn
= bpy
.context
.scene
.atom_blend
359 choose_objects("ATOM_RADIUS_ALL",
369 # Button for decreasing the radii of all selected atoms
370 class RadiusAllSmallerButton(Operator
):
371 bl_idname
= "atom_blend.radius_all_smaller"
372 bl_label
= "Smaller ..."
373 bl_description
= "Decrease the radii of selected atoms"
375 def execute(self
, context
):
376 scn
= bpy
.context
.scene
.atom_blend
377 choose_objects("ATOM_RADIUS_ALL",
387 # Button for increasing the radii of all selected sticks
388 class SticksAllBiggerButton(Operator
):
389 bl_idname
= "atom_blend.sticks_all_bigger"
390 bl_label
= "Bigger ..."
391 bl_description
= "Increase the radii of selected sticks"
393 def execute(self
, context
):
394 scn
= bpy
.context
.scene
.atom_blend
395 choose_objects("STICKS_RADIUS_ALL",
405 # Button for decreasing the radii of all selected sticks
406 class SticksAllSmallerButton(Operator
):
407 bl_idname
= "atom_blend.sticks_all_smaller"
408 bl_label
= "Smaller ..."
409 bl_description
= "Decrease the radii of selected sticks"
411 def execute(self
, context
):
412 scn
= bpy
.context
.scene
.atom_blend
413 choose_objects("STICKS_RADIUS_ALL",