Skip to content
Snippets Groups Projects
Commit d3bcfd68 authored by Clemens Barth's avatar Clemens Barth
Browse files

Dear all.

Here comes version 1.2 !

New 
===
1. Double and tripple bonds can now be displayed. The option 'bonds' needs to be
checked. One can also choose the distance between the sticks.

2. If the bool 'smooth' is checked the shape of the sticks is more round.  

Changes
=======
- Buttons, which depend on other buttons, are grayed out as soon as the
'master button' is deactivated.
- Other small bug fixes


With this version 1.2 I consider the PDB project as 'accomplished' so far. 
Of course, I will keep an eye on any critics, changes, bug fixes and so on. 
Please, let me know if you find any bugs. Thanks.



Happy New Year!




Blendphys 


parent 70de5e77
Branches
Tags
No related merge requests found
......@@ -20,7 +20,7 @@ bl_info = {
"name": "PDB Atomic Blender",
"description": "Loading and manipulating atoms from PDB files",
"author": "Clemens Barth",
"version": (1,1),
"version": (1,2),
"blender": (2,6),
"api": 31236,
"location": "File -> Import -> PDB (.pdb), Panel: View 3D - Tools",
......@@ -58,24 +58,9 @@ class CLASS_atom_pdb_panel(Panel):
#bl_context = "physics"
# This could be also an option ... :
bl_space_type = "VIEW_3D"
#bl_region_type = "TOOLS"
bl_region_type = "TOOL_PROPS"
# This 'poll thing' has taken 3 hours of a hard search and understanding.
# I explain it in the following from my point of view:
#
# Before this class is entirely treaten (here: drawing the panel) the
# poll method is called first. Basically, some conditions are
# checked before other things in the class are done afterwards. If a
# condition is not valid, one returns 'False' such that nothing further
# is done. 'True' means: 'Go on'
#
# In the case here, it is verified if the ATOM_PDB_FILEPATH variable contains
# a name. If not - and this is the case directly after having started the
# script - the panel does not appear because 'False' is returned. However,
# as soon as a file has been chosen, the panel appears because
# ATOM_PDB_FILEPATH contains a name.
#
# Please, correct me if I'm wrong.
@classmethod
def poll(self, context):
if import_pdb.ATOM_PDB_FILEPATH == "":
......@@ -106,21 +91,36 @@ class CLASS_atom_pdb_panel(Panel):
box = layout.box()
row = box.row()
col = row.column(align=True)
col = row.column()
col.prop(scn, "use_atom_pdb_mesh")
col = row.column()
col.label(text="Scaling factors")
row = box.row()
col = row.column(align=True)
col.active = scn.use_atom_pdb_mesh
col.prop(scn, "atom_pdb_mesh_azimuth")
col.prop(scn, "atom_pdb_mesh_zenith")
col = row.column(align=True)
col.label(text="Scaling factors")
col.prop(scn, "atom_pdb_scale_ballradius")
col.prop(scn, "atom_pdb_scale_distances")
row = box.row()
col = row.column()
col = row.column()
col.prop(scn, "use_atom_pdb_sticks")
row = box.row()
row.active = scn.use_atom_pdb_sticks
col = row.column(align=True)
col.prop(scn, "atom_pdb_sticks_sectors")
col.prop(scn, "atom_pdb_sticks_radius")
col = row.column(align=True)
col.prop(scn, "use_atom_pdb_sticks_color")
col.prop(scn, "use_atom_pdb_sticks_smooth")
col.prop(scn, "use_atom_pdb_sticks_bonds")
row = box.row()
row.active = scn.use_atom_pdb_sticks
col = row.column(align=True)
col = row.column(align=True)
col.active = scn.use_atom_pdb_sticks and scn.use_atom_pdb_sticks_bonds
col.prop(scn, "atom_pdb_sticks_dist")
row = box.row()
row.prop(scn, "use_atom_pdb_center")
row = box.row()
......@@ -129,7 +129,6 @@ class CLASS_atom_pdb_panel(Panel):
col.prop(scn, "use_atom_pdb_lamp")
col = row.column()
col.operator("atom_pdb.button_reload")
# TODO, use lanel() instead
col.prop(scn, "atom_pdb_number_atoms")
row = box.row()
row.operator("atom_pdb.button_distance")
......@@ -137,6 +136,7 @@ class CLASS_atom_pdb_panel(Panel):
row = layout.row()
row.label(text="Modify atom radii")
box = layout.box()
row = box.row()
row.label(text="All changes concern:")
......@@ -219,7 +219,7 @@ class CLASS_atom_pdb_IO(bpy.types.PropertyGroup):
name = "Object to origin", default=True,
description = "Put the object into the global origin")
scn.use_atom_pdb_sticks = BoolProperty(
name="Use sticks", default=False,
name="Use sticks", default=True,
description="Do you want to display the sticks?")
scn.atom_pdb_sticks_sectors = IntProperty(
name = "Sector", default=20, min=0,
......@@ -228,8 +228,17 @@ class CLASS_atom_pdb_IO(bpy.types.PropertyGroup):
name = "Radius", default=0.1, min=0.0,
description ="Radius of a stick")
scn.use_atom_pdb_sticks_color = BoolProperty(
name="Color", default=False,
name="Color", default=True,
description="The sticks appear in the color of the atoms")
scn.use_atom_pdb_sticks_smooth = BoolProperty(
name="Smooth", default=False,
description="The sticks are round (sectors are not visible)")
scn.use_atom_pdb_sticks_bonds = BoolProperty(
name="Bonds", default=False,
description="Show double and tripple bonds.")
scn.atom_pdb_sticks_dist = FloatProperty(
name="Distance", default = 1.1, min=1.0, max=3.0,
description="Distance between sticks measured in stick diameter")
scn.atom_pdb_atomradius = EnumProperty(
name="Type of radius",
description="Choose type of atom radius",
......@@ -243,9 +252,8 @@ class CLASS_atom_pdb_IO(bpy.types.PropertyGroup):
name = "", description="Path to your custom data file",
maxlen = 256, default = "", subtype='FILE_PATH')
scn.atom_pdb_PDB_file = StringProperty(
name = "Path to file", default="",
name = "PDB file", default="",
description = "Path of the PDB file")
# TODO, remove this property, its used for display only!
scn.atom_pdb_number_atoms = StringProperty(name="",
default="Number", description = "This output shows "
"the number of atoms which have been loaded")
......@@ -435,8 +443,8 @@ class CLASS_atom_pdb_radius_all_smaller_button(Operator):
return {'FINISHED'}
# Button for showing the sticks only - the radii of the atoms have the radius
# of the sticks
# Button for showing the sticks only - the radii of the atoms downscaled onto
# 90% of the stick radius
class CLASS_atom_pdb_radius_sticks_button(Operator):
bl_idname = "atom_pdb.radius_sticks"
bl_label = "Show sticks"
......@@ -448,7 +456,7 @@ class CLASS_atom_pdb_radius_sticks_button(Operator):
scn = bpy.context.scene
result = import_pdb.DEF_atom_pdb_radius_sticks(
scn.atom_pdb_sticks_radius,
scn.atom_pdb_sticks_radius * 0.9,
scn.atom_pdb_radius_how,
)
......@@ -476,19 +484,22 @@ class CLASS_atom_pdb_load_button(Operator):
center = scn.use_atom_pdb_center
sticks = scn.use_atom_pdb_sticks
sticks_col = scn.use_atom_pdb_sticks_color
sticks_sm = scn.use_atom_pdb_sticks_smooth
ssector = scn.atom_pdb_sticks_sectors
sradius = scn.atom_pdb_sticks_radius
stick_bond = scn.use_atom_pdb_sticks_bonds
stick_dist = scn.atom_pdb_sticks_dist
cam = scn.use_atom_pdb_cam
lamp = scn.use_atom_pdb_lamp
mesh = scn.use_atom_pdb_mesh
datafile = scn.atom_pdb_datafile
# Execute main routine an other time ... from the panel
atom_number = import_pdb.DEF_atom_pdb_main(
mesh, azimuth, zenith, bradius,
radiustype, bdistance, sticks, sticks_col,
ssector, sradius, center, cam, lamp, datafile,
)
mesh, azimuth, zenith, bradius, radiustype, bdistance,
sticks, sticks_col, sticks_sm, stick_bond,
stick_dist, ssector, sradius, center, cam, lamp, datafile)
scn.atom_pdb_number_atoms = str(atom_number) + " atoms"
return {'FINISHED'}
......@@ -513,6 +524,7 @@ class ImportPDB(Operator, ImportHelper):
col = row.column()
col.prop(scn, "use_atom_pdb_mesh")
col = row.column(align=True)
col.active = scn.use_atom_pdb_mesh
col.prop(scn, "atom_pdb_mesh_azimuth")
col.prop(scn, "atom_pdb_mesh_zenith")
......@@ -525,10 +537,21 @@ class ImportPDB(Operator, ImportHelper):
row = layout.row()
col = row.column()
col.prop(scn, "use_atom_pdb_sticks")
row = layout.row()
row.active = scn.use_atom_pdb_sticks
col = row.column(align=True)
col.prop(scn, "atom_pdb_sticks_sectors")
col.prop(scn, "atom_pdb_sticks_radius")
col = row.column(align=True)
col.prop(scn, "use_atom_pdb_sticks_color")
col.prop(scn, "use_atom_pdb_sticks_smooth")
col.prop(scn, "use_atom_pdb_sticks_bonds")
row = layout.row()
row.active = scn.use_atom_pdb_sticks
col = row.column(align=True)
col = row.column(align=True)
col.active = scn.use_atom_pdb_sticks and scn.use_atom_pdb_sticks_bonds
col.prop(scn, "atom_pdb_sticks_dist")
row = layout.row()
row.prop(scn, "use_atom_pdb_center")
......@@ -552,18 +575,22 @@ class ImportPDB(Operator, ImportHelper):
center = scn.use_atom_pdb_center
sticks = scn.use_atom_pdb_sticks
sticks_col = scn.use_atom_pdb_sticks_color
sticks_sm = scn.use_atom_pdb_sticks_smooth
ssector = scn.atom_pdb_sticks_sectors
sradius = scn.atom_pdb_sticks_radius
stick_bond = scn.use_atom_pdb_sticks_bonds
stick_dist = scn.atom_pdb_sticks_dist
cam = scn.use_atom_pdb_cam
lamp = scn.use_atom_pdb_lamp
mesh = scn.use_atom_pdb_mesh
datafile = scn.atom_pdb_datafile
# Execute main routine
atom_number = import_pdb.DEF_atom_pdb_main(
mesh, azimuth, zenith, bradius,
radiustype, bdistance, sticks, sticks_col,
ssector, sradius, center, cam, lamp, datafile)
mesh, azimuth, zenith, bradius, radiustype, bdistance,
sticks, sticks_col, sticks_sm, stick_bond,
stick_dist, ssector, sradius, center, cam, lamp, datafile)
scn.atom_pdb_number_atoms = str(atom_number) + " atoms"
......
......@@ -25,7 +25,7 @@
#
# Start of project : 2011-08-31 by Clemens Barth
# First publication in Blender : 2011-11-11
# Last modified : 2011-12-26
# Last modified : 2011-12-30
#
# Acknowledgements: Thanks to ideasman, meta_androcto, truman, kilon,
# dairin0d, PKHG, Valter, etc
......@@ -35,8 +35,10 @@ import bpy
import io
import math
import os
import copy
from math import pi, cos, sin
from mathutils import Vector, Matrix
from copy import copy
# These are variables, which contain the name of the PDB file and
# the path of the PDB file.
......@@ -207,10 +209,12 @@ class CLASS_atom_pdb_atom(object):
# This is the class, which stores the two atoms of one stick.
class CLASS_atom_pdb_stick(object):
__slots__ = ('atom1', 'atom2')
def __init__(self, atom1, atom2):
__slots__ = ('atom1', 'atom2', 'number', 'dist')
def __init__(self, atom1, atom2, number, dist):
self.atom1 = atom1
self.atom2 = atom2
self.number = number
self.dist = dist
# -----------------------------------------------------------------------------
......@@ -492,7 +496,9 @@ def DEF_atom_pdb_radius_sticks(radius, how):
return True
# This reads a custom data file.
# -----------------------------------------------------------------------------
# The custom data file
def DEF_atom_pdb_custom_datafile(path_datafile):
if path_datafile == "":
......@@ -560,7 +566,9 @@ def DEF_atom_pdb_custom_datafile(path_datafile):
def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith,
Ball_radius_factor,radiustype,Ball_distance_factor,
use_sticks,use_sticks_color,Stick_sectors,Stick_diameter,put_to_center,
use_sticks,use_sticks_color,use_sticks_smooth,
use_sticks_bonds,Stick_dist,
Stick_sectors,Stick_diameter,put_to_center,
use_camera,use_lamp,path_datafile):
# The list of all atoms as read from the PDB file.
......@@ -849,10 +857,34 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith,
atom1 = atom_list[0]
# For all the other atoms in the list do:
for each_atom in atom_list[1:]:
# The second, third, ... partner atom
atom2 = each_atom
for atom2 in atom_list[1:]:
if use_sticks_bonds == True:
number = atom_list[1:].count(atom2)
if number == 2 or number == 3:
basis_list = list(set(atom_list[1:]))
if len(basis_list) > 1:
basis1 = (all_atoms[atom1-1].location
- all_atoms[basis_list[0]-1].location)
basis2 = (all_atoms[atom1-1].location
- all_atoms[basis_list[1]-1].location)
plane_n = basis1.cross(basis2)
dist_n = (all_atoms[atom1-1].location
- all_atoms[atom2-1].location)
dist_n = dist_n.cross(plane_n)
dist_n = dist_n / dist_n.length
else:
dist_n = Vector((0,0,0))
elif number > 3:
number = 1
dist_n = None
else:
dist_n = None
else:
number = 1
dist_n = None
# Note that in a PDB file, sticks of one atom pair can appear a
# couple of times. (Only god knows why ...)
......@@ -869,7 +901,7 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith,
# If the stick is not yet registered (FLAG_BAR == False), then
# register it!
if FLAG_BAR == False:
all_sticks.append(CLASS_atom_pdb_stick(atom1,atom2))
all_sticks.append(CLASS_atom_pdb_stick(atom1,atom2,number,dist_n))
Number_of_sticks += 1
j += 1
......@@ -1169,27 +1201,79 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith,
continue
sticks_list = []
for stick in all_sticks:
dv = all_atoms[stick.atom1-1].location - all_atoms[stick.atom2-1].location
n = dv / dv.length
if atom_type[0] == all_atoms[stick.atom1-1].name:
location = all_atoms[stick.atom1-1].location
name = "_" + all_atoms[stick.atom1-1].name
material = all_atoms[stick.atom1-1].material
sticks_list.append([name, location, dv, material])
if atom_type[0] == all_atoms[stick.atom2-1].name:
location = all_atoms[stick.atom1-1].location - n * dl * int(math.ceil(dv.length / (2.0 * dl)))
name = "_" + all_atoms[stick.atom2-1].name
material = all_atoms[stick.atom2-1].material
sticks_list.append([name, location, dv, material])
for repeat in range(stick.number):
atom1 = copy(all_atoms[stick.atom1-1].location)
atom2 = copy(all_atoms[stick.atom2-1].location)
dist = Stick_diameter * Stick_dist
if stick.number == 2:
if repeat == 0:
atom1 += (stick.dist * dist)
atom2 += (stick.dist * dist)
if repeat == 1:
atom1 -= (stick.dist * dist)
atom2 -= (stick.dist * dist)
if stick.number == 3:
if repeat == 0:
atom1 += (stick.dist * dist)
atom2 += (stick.dist * dist)
if repeat == 2:
atom1 -= (stick.dist * dist)
atom2 -= (stick.dist * dist)
dv = atom1 - atom2
n = dv / dv.length
if atom_type[0] == all_atoms[stick.atom1-1].name:
location = atom1
name = "_" + all_atoms[stick.atom1-1].name
material = all_atoms[stick.atom1-1].material
sticks_list.append([name, location, dv, material])
if atom_type[0] == all_atoms[stick.atom2-1].name:
location = atom1 - n * dl * int(math.ceil(dv.length / (2.0 * dl)))
name = "_" + all_atoms[stick.atom2-1].name
material = all_atoms[stick.atom2-1].material
sticks_list.append([name, location, dv, material])
sticks_all_lists.append(sticks_list)
else:
sticks_list = []
for stick in all_sticks:
dv = all_atoms[stick.atom1-1].location - all_atoms[stick.atom2-1].location
n = dv / dv.length
location = all_atoms[stick.atom1-1].location
material = stick_material
sticks_list.append(["", location, dv, material])
if stick.number > 3:
stick.number = 1
for repeat in range(stick.number):
atom1 = copy(all_atoms[stick.atom1-1].location)
atom2 = copy(all_atoms[stick.atom2-1].location)
dist = Stick_diameter * Stick_dist
if stick.number == 2:
if repeat == 0:
atom1 += (stick.dist * dist)
atom2 += (stick.dist * dist)
if repeat == 1:
atom1 -= (stick.dist * dist)
atom2 -= (stick.dist * dist)
if stick.number == 3:
if repeat == 0:
atom1 += (stick.dist * dist)
atom2 += (stick.dist * dist)
if repeat == 2:
atom1 -= (stick.dist * dist)
atom2 -= (stick.dist * dist)
dv = atom1 - atom2
n = dv / dv.length
location = atom1
material = stick_material
sticks_list.append(["", location, dv, material])
sticks_all_lists.append(sticks_list)
......@@ -1238,8 +1322,12 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith,
current_layers = bpy.context.scene.layers
stick_cylinder = DEF_atom_pdb_build_stick(Stick_diameter, dl, Stick_sectors)
stick_cylinder.active_material = stick[3]
stick_cylinder.parent = new_mesh
if use_sticks_smooth == True:
for face in stick_cylinder.data.faces:
face.use_smooth = True
stick_cylinder.parent = new_mesh
new_mesh.dupli_type = 'FACES'
atom_object_list.append(new_mesh)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment