1. New feature: The ionic radius can now be chosen for the ball radius,
authorClemens Barth <barth@root-1.de>
Tue, 8 Jan 2013 06:38:02 +0000 (06:38 +0000)
committerClemens Barth <barth@root-1.de>
Tue, 8 Jan 2013 06:38:02 +0000 (06:38 +0000)
depending on the charge state (-4e ... +7e). Changes of the ball radii are
only done if objects are selected.

2. Code cleaning.

Blendphys.

io_atomblend_utilities/__init__.py
io_atomblend_utilities/io_atomblend_utilities.py

index fef302b9276b0002fc96d50b9098e3be17011c34..49a7facdddd7bed7df827be47b12c9acb2cdcaea 100644 (file)
@@ -24,7 +24,7 @@
 #
 #  Start of project              : 2011-12-01 by Clemens Barth
 #  First publication in Blender  : 2012-11-03
-#  Last modified                 : 2013-01-03
+#  Last modified                 : 2013-01-08
 #
 #  Acknowledgements 
 #  ================
@@ -60,8 +60,7 @@ from . import io_atomblend_utilities
 # -----------------------------------------------------------------------------
 #                                                                           GUI
 
-# This is the panel, which can be used to prepare the scene.
-# It is loaded after the file has been chosen via the menu 'File -> Import'
+# The panel.
 class PreparePanel(Panel):
     bl_label       = "Atomic Blender Utilities"
     bl_space_type  = "VIEW_3D"
@@ -72,7 +71,6 @@ class PreparePanel(Panel):
         scn    = context.scene.atom_blend
 
         row = layout.row()
-        row.label(text="Custom data file")
         box = layout.box()
         row = box.row()
         row.label(text="Custom data file")
@@ -95,6 +93,9 @@ class PreparePanel(Panel):
         row = box.row()
         row.prop(scn, "radius_type")
         row = box.row()
+        row.active = (scn.radius_type == '3')
+        row.prop(scn, "radius_type_ionic")
+        row = box.row()
         row.label(text="2. Change atom radii in pm")
         row = box.row()
         row.prop(scn, "radius_pm_name")
@@ -115,6 +116,7 @@ class PreparePanel(Panel):
         row.operator( "atom_blend.separate_atom" )
 
 
+# The properties of buttons etc. in the panel.
 class PanelProperties(bpy.types.PropertyGroup):
 
     def Callback_radius_type(self, context):
@@ -123,7 +125,8 @@ class PanelProperties(bpy.types.PropertyGroup):
                                               scn.radius_how, 
                                               None,
                                               None,
-                                              scn.radius_type) 
+                                              scn.radius_type,
+                                              scn.radius_type_ionic) 
     def Callback_radius_pm(self, context):
         scn = bpy.context.scene.atom_blend
         io_atomblend_utilities.choose_objects("radius_pm", 
@@ -131,6 +134,7 @@ class PanelProperties(bpy.types.PropertyGroup):
                                               None,
                                               [scn.radius_pm_name,
                                               scn.radius_pm],
+                                              None,
                                               None) 
         
     datafile = StringProperty(
@@ -152,12 +156,28 @@ class PanelProperties(bpy.types.PropertyGroup):
                ('ALL_IN_LAYER',"all"," in active layer(s)")),
                default='ALL_ACTIVE',)
     radius_type = EnumProperty(
-        name="Type",
+        name="Type of radius",
         description="Which type of atom radii?",
         items=(('0',"predefined", "Use pre-defined radii"),
                ('1',"atomic", "Use atomic radii"),
-               ('2',"van der Waals","Use van der Waals radii")),
+               ('2',"van der Waals","Use van der Waals radii"),
+               ('3',"ionic radii", "Use ionic radii")),
                default='0',update=Callback_radius_type)
+    radius_type_ionic = EnumProperty(
+        name="Charge state",
+        description="Charge state of the ions if existing.",
+        items=(('0',"-4", "Charge state -4"),
+               ('1',"-3", "Charge state -3"),
+               ('2',"-2", "Charge state -2"),
+               ('3',"-1", "Charge state -1"),
+               ('5',"+1", "Charge state +1"),
+               ('6',"+2", "Charge state +2"),
+               ('7',"+3", "Charge state +3"),
+               ('8',"+4", "Charge state +4"),
+               ('9',"+5", "Charge state +5"),
+               ('10',"+6", "Charge state +6"),
+               ('11',"+7", "Charge state +7")),
+               default='3',update=Callback_radius_type)           
     radius_pm_name = StringProperty(
         name="", default="Atom name",
         description="Put in the name of the atom (e.g. Hydrogen)")
index ae8d531e161dbf103d29309f76d975c7d50ac176..277338e4c776dd4dbe0c65f84fdbfa81d0f8c067 100644 (file)
@@ -20,14 +20,8 @@ import os
 import bpy
 import bmesh
 
-# This variable contains the path of the XYZ file.
-# It is used almost everywhere, which explains why it
-# should stay global. First, it is empty and gets 'filled' directly
-# after having chosen the XYZ file (see 'class LoadXYZ' further below).
-
-
 # -----------------------------------------------------------------------------
-#                                                  Atom and element data
+#                                                         Atom and element data
 
 
 # This is a list that contains some data of all possible elements. The structure
@@ -150,13 +144,12 @@ ELEMENTS_DEFAULT = (
 (106,         "Stick",    "Stick", (  0.5,   0.5,   0.5), 1.00, 1.00, 1.00),
 )
 
-# This list here contains all data of the elements and will be used during
-# runtime. It is a list of classes.
-# During executing Atomic Blender, the list will be initialized with the fixed
-# data from above via the class structure below (ElementProp). We
-# have then one fixed list (above), which will never be changed, and a list of
-# classes with same data. The latter can be modified via loading a separate
-# custom data file for instance.
+# The list 'ELEMENTS' contains all data of the elements and will be used during
+# runtime. The list will be initialized with the fixed
+# data from above via the class below (ElementProp). One fixed list (above), 
+# which cannot be changed, and a list of classes with same data (ELEMENTS) exist.
+# The list 'ELEMENTS' can be modified by e.g. loading a separate custom
+# data file.
 ELEMENTS = []
 
 # This is the class, which stores the properties for one element.
@@ -171,9 +164,6 @@ class ElementProp(object):
         self.radii_ionic = radii_ionic
 
 
-# -----------------------------------------------------------------------------
-#                                                          Some small routines
-
 # This function measures the distance between two objects (atoms),
 # which are active.
 def distance():
@@ -212,7 +202,12 @@ def distance():
     return dist
 
 
-def choose_objects(how, who, radius_all, radius_pm, radius_type):
+def choose_objects(how, 
+                   who, 
+                   radius_all, 
+                   radius_pm, 
+                   radius_type, 
+                   radius_type_ionic):
 
     if who == "ALL_IN_LAYER":
 
@@ -237,14 +232,16 @@ def choose_objects(how, who, radius_all, radius_pm, radius_type):
                                    obj.children[0],
                                    radius_all, 
                                    radius_pm, 
-                                   radius_type)
+                                   radius_type,
+                                   radius_type_ionic)
             else:
                 if obj.type in {'SURFACE', 'MESH', 'META'}:
                     modify_objects(how, 
                                    obj,  
                                    radius_all, 
                                    radius_pm, 
-                                   radius_type)
+                                   radius_type,
+                                   radius_type_ionic)
     if who == "ALL_ACTIVE":
         for obj in bpy.context.selected_objects:
             if len(obj.children) != 0:
@@ -253,19 +250,26 @@ def choose_objects(how, who, radius_all, radius_pm, radius_type):
                                    obj.children[0],
                                    radius_all, 
                                    radius_pm, 
-                                   radius_type)
+                                   radius_type,
+                                   radius_type_ionic)
             else:
                 if obj.type in {'SURFACE', 'MESH', 'META'}:
                     modify_objects(how, 
                                    obj,
                                    radius_all, 
                                    radius_pm, 
-                                   radius_type)
+                                   radius_type,
+                                   radius_type_ionic)
 
 
 
-# Routine to modify the radii in picometer of a specific type of atom
-def modify_objects(how, obj, radius_all, radius_pm, radius_type):
+# Modifying the radii in picometer of a specific type of atom
+def modify_objects(how, 
+                   obj, 
+                   radius_all, 
+                   radius_pm, 
+                   radius_type, 
+                   radius_type_ionic):
 
     # Radius pm 
     if how == "radius_pm":
@@ -278,12 +282,30 @@ def modify_objects(how, obj, radius_all, radius_pm, radius_type):
               
     # Radius type 
     if how == "radius_type":
-        for element in ELEMENTS:
+        for element in ELEMENTS:                
             if element.name in obj.name:
-                obj.scale = (element.radii[int(radius_type)],) * 3
-
-
-# Read the default element list.
+                # For ionic radii
+                if radius_type == '3':
+                    charge_states = element.radii_ionic[::2]
+                    charge_radii =  element.radii_ionic[1::2]
+                    charge_state_chosen = int(radius_type_ionic) - 4
+                    
+                    find = (lambda searchList, elem: 
+                            [[i for i, x in enumerate(searchList) if x == e] 
+                            for e in elem])
+                    index = find(charge_states,[charge_state_chosen])[0]
+
+                    # Is there a charge state?                    
+                    if index != []:
+                        #print(element.name, index[0], charge_radii[index[0]])
+                        obj.scale = (charge_radii[index[0]],) * 3
+                                            
+                # For atomic and van der Waals radii.
+                else:        
+                    obj.scale = (element.radii[int(radius_type)],) * 3
+
+
+# Initialization of the list 'ELEMENTS'.
 def read_elements():
 
     del ELEMENTS[:]
@@ -294,14 +316,14 @@ def read_elements():
         radii = [item[4],item[5],item[6]]
         # The handling of the ionic radii will be done later. So far, it is an
         # empty list.
-        radii_ionic = []
-
+        radii_ionic = item[7:]
+        
         li = ElementProp(item[0],item[1],item[2],item[3],
                                      radii,radii_ionic)
         ELEMENTS.append(li)
 
 
-# Change color and radii by uisnf the list of elements.
+# Changing color and radii by using the list of elements.
 def custom_datafile_change_atom_props():
 
     for obj in bpy.context.selected_objects:
@@ -320,7 +342,7 @@ def custom_datafile_change_atom_props():
                         obj.active_material.diffuse_color = element.color
 
 
-# This reads a custom data file.
+# Reading a custom data file.
 def custom_datafile(path_datafile):
 
     if path_datafile == "":
@@ -380,7 +402,7 @@ def custom_datafile(path_datafile):
     return True
 
 
-# Routine for separating atoms from a dupliverts strucutre.
+# Separating atoms from a dupliverts strucutre.
 def separate_atoms(scn):
 
     # Get first all important properties from the atoms, which the user