

####################################################################################################
#                                                                                                  #
#  #######   #######   #######    #####    #######   ####     #######  ###    ###  #######         #
#   ##   ##   ##   ##   ##   ##  ##   ##    ##   ##   ##       ##  ##   ###   ##    ##   ##        #
#   ##   ##   ##   ##   ##   ##       ##    ##   ##   ##       ##       ####  ##    ##   ##        #
#   ######    ##   ##   ######     ###      ######    ##       #####    ## ## ##    ##   ##        #
#   ##        ##   ##   ##   ##   ##        ##   ##   ##       ##       ##  ####    ##   ##        #
#   ##        ##   ##   ##   ##  ##   ##    ##   ##   ##  ##   ##  ##   ##   ###    ##   ##        #
#  ####      #######   #######   #######   #######   #######  #######  ###    ###  #######   V1.2  #
#                                                                                                  #
####################################################################################################
#
# pdb Molecule 2 Blender 3d Model Converter by Malte Reimold 2006
#
# Modes: 
# 	1. Ball
# 		creates a ball model with overlapping spheres when using the standard parameters
#		the ball sizes can be adjusted by choosing a constant scaling factor (atom scale)
#		as well as a constant summand (atom sum) that is added to the ball size. 
#		With atom scale = 1	and atom sum = 0 one will get the covalent radius for any atom defined.
#		With atom scale = 0 and atom sum > 0 the model will have uniform ball sizes.
#	2. Sticks
#		creates a stick model. 
#		The stick diameter can be chosen here (Stick Thickness).
#		Until now the regular stick mode (as well as stick and ball) does only work for less than 
#		10000 atoms.
#	3. Sticks and Balls
#		A combination of ball and stick mode. When using standard parameters the atoms are scaled 
#		down a little bit.
#	4. DNA Backbone Follow
#		When turning on this option a stick model will be formed connecting the phosphorous atoms 
#		of oligonucleotide backbones. This works even for systems with more than 10000 atoms.
#
# Model refinement:
#	The refinement of spheres and sticks can be chosen. With higher values the model becomes more 
#   detailed.
#
# The pdb 2 blender converter is still experimental. Please report problems and errors to me.
#
# Version History
#	v1.2 Fixed some problems concerning pdb-file conventions. 
#	v1.1 Fixed some minor bugs.
# 
##############################################################################(c)2006MalteReimold




















import Blender
from Blender import *
from Blender.Draw import *
from math import *


editmode = Window.EditMode()
if editmode: Window.EditMode(0)
scene = Blender.Scene.getCurrent ()

matlist = str(Material.Get ())

if not ('[Material "C"]' in matlist):
	mat = Material.New('C')
	mat.R = 0.0
	mat.G = 0.0
	mat.B = 0.0

if not ('[Material "H"]' in matlist):
	mat = Material.New('H')
	mat.R = 1.0
	mat.G = 1.0
	mat.B = 1.0
	
if not ('[Material "P"]' in matlist):
	mat = Material.New('P')
	mat.R = 0.0
	mat.G = 0.75
	mat.B = 0.0	
	
if not ('[Material "B"]' in matlist):
	mat = Material.New('B')
	mat.R = 0.8
	mat.G = 0.6
	mat.B = 0.1
	
if not ('[Material "P"]' in matlist):
	mat = Material.New('P')
	mat.R = 0.9
	mat.G = 0.95
	mat.B = 0.1
	
if not ('[Material "N"]' in matlist):
	mat = Material.New('N')
	mat.R = 0.0
	mat.G = 0.0
	mat.B = 1.0
	
if not ('[Material "O"]' in matlist):
	mat = Material.New('O')
	mat.R = 1.0
	mat.G = 0.0
	mat.B = 0.0

if not ('[Material "S"]' in matlist):
	mat = Material.New('S')
	mat.R = 1.0
	mat.G = 1.0
	mat.B = 0.0
	
if not ('[Material "anyatom"]' in matlist):
	mat = Material.New('anyatom')
	mat.R = 0.8
	mat.G = 1.0
	mat.B = 1.0
	
if not ('[Material "sticks"]' in matlist):
	mat = Material.New('sticks')
	mat.R = 0.8
	mat.G = 0.8
	mat.B = 0.8


def ball(name, type, x, y, z):
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks
	# Objekt erstellen
	ob = Object.New('Mesh', name)
	# Mesh erstellen
	me = Mesh.New(name)
	# Ball erstellen
	a = 0.0000	
	b = 0.0000
	vcount = 0
	da = 360.00 / refineballs.val
	db = 360.00 / refineballs.val
	#da = 30.0
	#db = 30.0
	dx = 0.0
	dy = 0.0
	dz = 0.0
	pi = asin(1)
	if type == "C":	
		radius = 0.85
		mat = Material.Get('C')
	elif type == "H": 
		radius = 0.6
		mat = Material.Get('H')
	elif type == "B": 
		radius = 0.83
		mat = Material.Get('B')
	elif type == "N": 
		radius = 0.71
		mat = Material.Get('N')
	elif type == "O": 
		radius = 0.775
		mat = Material.Get('O')
	elif type == "P": 
		radius = 0.76
		mat = Material.Get('P')
	else: 
		radius = 0.9
		mat = Material.Get('anyatom')
		
	me.materials = [mat]
	
	radius = radius * scatom.val + sumatom.val
	
	
	# erster Punkt
	me.verts.extend(0, 0, radius)
	a = a + da
	
	# Kappe
		
	while b < 360:
		dz = radius*cos(a/90*pi)
		dx = radius*sin(a/90*pi)*sin(b/90*pi)
		dy = radius*sin(a/90*pi)*cos(b/90*pi)
		b = b + db
		me.verts.extend(dx, dy, dz)
		vcount = vcount + 1
		if vcount > 1:
			me.faces.extend([me.verts[0],me.verts[vcount],me.verts[vcount-1]])
	
	me.faces.extend([me.verts[0],me.verts[1],me.verts[vcount]])
	
	b = 0.00
	kcount = 0
	vvcount = 0
	a = a + da
	
	
	while a < 180:
		while b < 360:
			dz = radius*cos(a/90*pi)
			dx = radius*sin(a/90*pi)*sin(b/90*pi)
			dy = radius*sin(a/90*pi)*cos(b/90*pi)
			me.verts.extend(dx, dy, dz)
			vcount = vcount + 1
			vvcount = vvcount + 1
			if vvcount > 1:
				me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
				if b == 360-db:
					me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
			b = b + db
		kcount = kcount + 1
		b = 0
		vvcount = 0
		a = a + da
		
	# letzter Punkt
	me.verts.extend(0, 0, -radius)
	vcount = vcount + 1
	b = 0
	while b < 360-db:
		me.faces.extend([me.verts[vcount],me.verts[vcount-int(b/db)-2],me.verts[vcount-int(b/db)-1]])
		b = b + db
	
	me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int((360-db)/db)-1]])
	eins = 1
	for face in me.faces:
		face.smooth=1
	

	ob.link (me)
	ob.loc = (x,y,z)
	scene.link (ob)
	
def stick1(x1, y1, z1, x2, y2, z2, radius):
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks
	# Objekt erstellen
	ob = Object.New('Mesh')
	# Mesh erstellen
	me = Mesh.New()
	mat = Material.Get('sticks')
	me.materials = [mat]
	# Stick erstellen
	a = 0.0000	
	b = 0.0000
	vcount = 0
	da = 360.00 / refinesticks.val
	db = 360.00 / refinesticks.val
	dx = 0.0
	dy = 0.0
	dz = 0.0
	pi = asin(1)
	laenge = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2))
	wsz = atan2((y1-y2), (x1-x2))
	wz = acos((z1-z2)/laenge)
	
	
	# erster Punkt
	me.verts.extend(0, 0, laenge/2+radius)
	a = a + da
	
	# Kappe
		
	while b < 360:
		dz = radius*cos(a/90*pi)
		dx = radius*sin(a/90*pi)*sin(b/90*pi)
		dy = radius*sin(a/90*pi)*cos(b/90*pi)
		b = b + db
		me.verts.extend(dx, dy, dz+laenge/2)
		vcount = vcount + 1
		if vcount > 1:
			me.faces.extend([me.verts[0],me.verts[vcount],me.verts[vcount-1]])
	
	me.faces.extend([me.verts[0],me.verts[1],me.verts[vcount]])
	
	b = 0.00
	kcount = 0
	vvcount = 0
	a = a + da
	
	
	while a < 90:
		while b < 360:
			dz = radius*cos(a/90*pi)
			dx = radius*sin(a/90*pi)*sin(b/90*pi)
			dy = radius*sin(a/90*pi)*cos(b/90*pi)
			me.verts.extend(dx, dy, dz+laenge/2)
			vcount = vcount + 1
			vvcount = vvcount + 1
			if vvcount > 1:
				me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
				if b == 360-db:
					me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
			b = b + db
		kcount = kcount + 1
		b = 0
		vvcount = 0
		a = a + da
		
	a = 90
	b = 0.00
	vvcount = 0
	
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, laenge/2)
		vcount = vcount + 1
		vvcount = vvcount + 1
		if vvcount > 1:
			me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
			if b == 360-db:
				me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
		b = b + db
	kcount = kcount + 1
	b = 0.00
	vvcount = 0	
	
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, -laenge/2)
		vcount = vcount + 1
		vvcount = vvcount + 1
		if vvcount > 1:
			me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
			if b == 360-db:
				me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
		b = b + db
	kcount = kcount + 1
	b = 0.00
	vvcount = 0	
	
	while a < 180:
		while b < 360:
			dz = radius*cos(a/90*pi)
			dx = radius*sin(a/90*pi)*sin(b/90*pi)
			dy = radius*sin(a/90*pi)*cos(b/90*pi)
			me.verts.extend(dx, dy, dz-laenge/2)
			vcount = vcount + 1
			vvcount = vvcount + 1
			if vvcount > 1:
				me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
				if b == 360-db:
					me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
			b = b + db
		kcount = kcount + 1
		b = 0.00
		vvcount = 0
		a = a + da
		
	# letzter Punkt
	me.verts.extend(0, 0, -laenge/2-radius)
	vcount = vcount + 1
	b = 0
	while b < 360-db:
		me.faces.extend([me.verts[vcount],me.verts[vcount-int(b/db)-2],me.verts[vcount-int(b/db)-1]])
		b = b + db
	
	me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int((360-db)/db)-1]])
	eins = 1
	for face in me.faces:
		face.smooth=1
	
	
	ob.link (me)
	x1 = float(x1)
	y1 = float(y1)
	z1 = float(z1)
	x2 = float(x2)
	y2 = float(y2)
	z2 = float(z2)
	ob.loc = (float(x1+x2)/2,(y1+y2)/2,(z1+z2)/2)
	ob.RotY = wz
	ob.RotZ = wsz
	scene.link (ob)

def stick2(x1, y1, z1, x2, y2, z2, radius):
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks
	# Objekt erstellen
	ob = Object.New('Mesh')
	# Mesh erstellen
	me = Mesh.New()
	mat = Material.Get('sticks')
	me.materials = [mat]
	# Stick erstellen
	b = 0.0000
	vcount = -1
	db = 360.00 / refinesticks.val
	dx = 0.0
	dy = 0.0
	dz = 0.0
	pi = asin(1)
	laenge = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2))
	wsz = atan2((y1-y2), (x1-x2))
	wz = acos((z1-z2)/laenge)
	
	
	# erster Punkt
	
	# Kappe	
	
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, laenge/2)
		me.verts.extend(dx, dy, -laenge/2)
		vcount = vcount + 2
		if vcount > 2:
			me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-3],me.verts[vcount-2]])
			if b == 360-db:
				me.faces.extend([me.verts[0],me.verts[vcount-1],me.verts[vcount],me.verts[1]])
		b = b + db
	
	for face in me.faces:
		face.smooth=1
	
	ob.link (me)
	x1 = float(x1)
	y1 = float(y1)
	z1 = float(z1)
	x2 = float(x2)
	y2 = float(y2)
	z2 = float(z2)
	ob.loc = (float(x1+x2)/2,(y1+y2)/2,(z1+z2)/2)
	ob.RotY = wz
	ob.RotZ = wsz
	scene.link (ob)


def stick3(x1, y1, z1, type1, x2, y2, z2, type2, radius):
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks
	# Objekt erstellen
	ob = Object.New('Mesh')
	# Mesh erstellen
	me = Mesh.New()
	if type1 in ['C', 'H', 'B', 'N', 'O', 'P']:
		mat = Material.Get(type1)
	else: mat = Material.Get('anyatom')
	me.materials = [mat]
	# Stick erste Haelfte erstellen
	a = 0.0000	
	b = 0.0000
	vcount = 0
	da = 360.00 / refinesticks.val
	db = 360.00 / refinesticks.val
	dx = 0.0
	dy = 0.0
	dz = 0.0
	pi = asin(1)
	laenge = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2))
	wsz = atan2((y1-y2), (x1-x2))
	wz = acos((z1-z2)/laenge)
	
	
	# erster Punkt
	me.verts.extend(0, 0, laenge/2+radius)
	a = a + da
	
	# Kappe
		
	while b < 360:
		dz = radius*cos(a/90*pi)
		dx = radius*sin(a/90*pi)*sin(b/90*pi)
		dy = radius*sin(a/90*pi)*cos(b/90*pi)
		b = b + db
		me.verts.extend(dx, dy, dz+laenge/2)
		vcount = vcount + 1
		if vcount > 1:
			me.faces.extend([me.verts[0],me.verts[vcount],me.verts[vcount-1]])
	
	me.faces.extend([me.verts[0],me.verts[1],me.verts[vcount]])
	
	b = 0
	kcount = 0
	vvcount = 0
	a = a + da
	
	
	while a < 90:
		while b < 360:
			dz = radius*cos(a/90*pi)
			dx = radius*sin(a/90*pi)*sin(b/90*pi)
			dy = radius*sin(a/90*pi)*cos(b/90*pi)
			me.verts.extend(dx, dy, dz+laenge/2)
			vcount = vcount + 1
			vvcount = vvcount + 1
			if vvcount > 1:
				me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
				if b == 360-db:
					me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
			b = b + db
		kcount = kcount + 1
		b = 0
		vvcount = 0
		a = a + da
		
	a = 90
	b = 0
	vvcount = 0
	
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, laenge/2)
		vcount = vcount + 1
		vvcount = vvcount + 1
		if vvcount > 1:
			me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
			if b == 360-db:
				me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
		b = b + db
	kcount = kcount + 1
	b = 0
	vvcount = 0	
	
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, 0)
		vcount = vcount + 1
		vvcount = vvcount + 1
		if vvcount > 1:
			me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
			if b == 360-db:
				me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
		b = b + db
	kcount = kcount + 1
	b = 0
	vvcount = 0	
	
	for face in me.faces:
		face.smooth=1
	
	
	ob.link (me)
	x1 = float(x1)
	y1 = float(y1)
	z1 = float(z1)
	x2 = float(x2)
	y2 = float(y2)
	z2 = float(z2)
	ob.loc = (float(x1+x2)/2,(y1+y2)/2,(z1+z2)/2)
	ob.RotY = wz
	ob.RotZ = wsz
	scene.link (ob)
	
	#zweite Haelfte vom Stick
	ob = Object.New('Mesh')
	# Mesh erstellen
	me = Mesh.New()
	if type2 in ['C', 'H', 'B', 'N', 'O', 'P']:
		mat = Material.Get(type2)
	else: mat = Material.Get('anyatom')
	me.materials = [mat]
	vcount = -1
			
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, 0)
		vcount = vcount + 1
		
		b = b + db
	
	kcount = kcount + 1
	b = 0
	vvcount = 0	
	
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, -laenge/2)
		vcount = vcount + 1
		vvcount = vvcount + 1
		if vvcount > 1:
			me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
			if b == 360-db:
				me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
		b = b + db
	kcount = kcount + 1
	b = 0
	vvcount = 0	
	
	while a < 180:
		while b < 360:
			dz = radius*cos(a/90*pi)
			dx = radius*sin(a/90*pi)*sin(b/90*pi)
			dy = radius*sin(a/90*pi)*cos(b/90*pi)
			me.verts.extend(dx, dy, dz-laenge/2)
			vcount = vcount + 1
			vvcount = vvcount + 1
			if vvcount > 1:
				me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
				if b == 360-db:
					me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
			b = b + db
		kcount = kcount + 1
		b = 0
		vvcount = 0
		a = a + da
		
	# letzter Punkt
	me.verts.extend(0, 0, -laenge/2-radius)
	vcount = vcount + 1
	b = 0
	while b < 360-db:
		me.faces.extend([me.verts[vcount],me.verts[vcount-int(b/db)-2],me.verts[vcount-int(b/db)-1]])
		b = b + db
	
	me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int((360-db)/db)-1]])
	eins = 1
	for face in me.faces:
		face.smooth=1
	
	
	ob.link (me)
	x1 = float(x1)
	y1 = float(y1)
	z1 = float(z1)
	x2 = float(x2)
	y2 = float(y2)
	z2 = float(z2)
	ob.loc = (float(x1+x2)/2,(y1+y2)/2,(z1+z2)/2)
	ob.RotY = wz
	ob.RotZ = wsz
	scene.link (ob)


def import_pdb(path):
	global structmode, scatom, sumatom, refineballs, refinesticks, scsticks, balls, sticks, hydros
	Blender.Window.WaitCursor(1)
	x, y, z, atom = [0], [0], [0], [0]
	file = open(path, 'r')
	for line in file.readlines():
		if len(line) == 0 or line == ('END'):
			pass
		elif line[:6] == 'HETATM' or line[:4] == 'ATOM':
			name = line[7:11]
			while name[:1]==' ': name = name[1:]
			if len(line) > 76: 
				atom0 = line[77:(len(line)-1)]
				while atom0[-1] == ' ': atom0 = atom0[:-1]
			else:
				atom0 = line[13:16]
				while atom0[-1] == ' ': atom0 = atom0[:-1]
				esym = [' ','1','2','3','4','5','6','7','8','9']
				for a in esym:
					if atom0[-1] == a: atom0 = atom0[:-1]
					if atom0[0] == a: atom0 = atom0[1:]
			atom.append (atom0)
			x0 = line[31:38]
			while x0[:1]==' ': x0 = x0[1:]
			y0 = line[39:46]
			while y0[:1]==' ': y0 = y0[1:]
			z0 = line[47:54]
			while z0[:1]==' ': z0 = z0[1:]
			
			x.append (float(x0))
			y.append (float(y0))
			z.append (float(z0))
			
			
			if balls:
				if atom[int(name)] == 'H':
					if hydros: 
						ball(name, atom[int(name)], x[int(name)],y[int(name)],z[int(name)])
				else: ball(name, atom[int(name)], x[int(name)],y[int(name)],z[int(name)])
					
		elif line[:3] == 'TER':
			name = 'platzhalter'
			atom.append ('platzhalter')
			x.append (0)
			y.append (0)
			z.append (0)
		elif line[:6] == 'CONECT':
			if sticks:
				con0 = line[6:11]
				while con0[:1]==' ': con0 = con0[1:]
				for i in range(0,4):
					if len(line) > (15 + 5 * i):
						if not line[(11+5*i):(16+5*i)] == '     ':
							con1 = line[(11+5*i):(16+5*i)]
							while con1[:1]==' ': con1 = con1[1:]
							if int(con1)> int(con0):
								if hydros:
									stick3(x[int(con0)], y[int(con0)], z[int(con0)], atom[int(con0)], x[int(con1)], y[int(con1)], z[int(con1)], atom[int(con1)], scsticks.val)
								else:
									if not (atom[int(con0)]=='H' or atom[int(con1)]=='H'):
										stick3(x[int(con0)], y[int(con0)], z[int(con0)], atom[int(con0)], x[int(con1)], y[int(con1)], z[int(con1)], atom[int(con1)], scsticks.val)

	scene.update()
	Blender.Redraw()		     
	Blender.Window.WaitCursor(0)

def import_p_follow(path):
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks
	Blender.Window.WaitCursor(1)
	x, y, z = 0, 0, 0
	pcount = 0
	file = open(path, 'r')
	for line in file.readlines():
		if len(line) == 0 or line[:3] == ('END') or line[:6] == ('CONECT'):
			pass
		elif line[:6] == 'HETATM' or line[:4] == 'ATOM':
			if len(line) > 76: 
				atom0 = line[77:(len(line)-1)]
				while atom0[-1] == ' ': atom0 = atom0[:-1]
			else:
				atom0 = line[13:16]
				while atom0[-1] == ' ': atom0 = atom0[:-1]
				esym = [' ','1','2','3','4','5','6','7','8','9']
				for a in esym:
					if atom0[-1] == a: atom0 = atom0[:-1]
					if atom0[0] == a: atom0 = atom0[1:]
			if atom0 == 'P':
				xold = x
				yold = y
				zold = z
				x0 = line[31:38]
				while x0[:1]==' ': x0 = x0[1:]
				y0 = line[39:46]
				while y0[:1]==' ': y0 = y0[1:]
				z0 = line[47:54]
				while z0[:1]==' ': z0 = z0[1:]
				x = float(x0)
				y = float(y0)
				z = float(z0)
				if line[30] == '-': x = 0 - x
				if line[38] == '-': y = 0 - y
				if line[46] == '-': z = 0 - z	
				abstandq = (x - xold) * (x - xold) + (y - yold) * (y - yold) + (z - zold)*(z - zold)
				if pcount > 0 and abstandq < 100.00:
					stick1(xold, yold, zold, x, y, z, scsticks.val)
				pcount = pcount + 1
		elif line[:3] == 'TER':
			pcount = 0
	scene.update()
	Blender.Redraw()	
	Blender.Window.WaitCursor(0)

def gui():
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks, hydros, bbut, sbbut, sbut, pbut
	bbut = Toggle('Balls',3, 40, 240, 80, 19, bbut.val)
	sbbut = Toggle('Sticks and Balls',4, 120, 240, 150, 19, sbbut.val)
	sbut = Toggle('Sticks',5, 270, 240, 80, 19, sbut.val)
	pbut = Toggle('DNA Backbone Follow',12, 40, 220, 310, 19, pbut.val)
	if hydros: Button('Hydrogens on',11, 40, 190, 310, 19)
	else: Button('Hydrogens off',11, 40, 190, 310, 19)
	if balls: scatom = Slider('Atom Scale :', 6, 40, 160, 310,19, scatom.val, 0.00, 4.00)
	if balls: sumatom = Slider('Atom Sum :', 7, 40, 140, 310,19, sumatom.val, 0.00, 2.00)
	if balls: refineballs = Slider('Atom Refinement :', 8, 40, 120, 310,19, refineballs.val, 4, 36)
	if sticks or pbut.val: scsticks = Slider('Stick Thickness :', 9, 40, 90, 310,19, scsticks.val, 0.00, 4.00)
	if sticks or pbut.val: refinesticks = Slider('Stick Refinement :', 10, 40, 70, 310,19, refinesticks.val, 4, 36)
	Button('Import',1, 40, 40, 155, 19)
	Button('Cancel',2, 195, 40, 155, 19)
	
def event(evt, val):
	if (evt == ESCKEY and not val): Exit()
		
def bevent(evt):
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks, hydros, bbut, sbbut, sbut, pbut
	if evt == 2: Exit()
	elif evt == 1: 
		if structmode == 'Backbone':
			Blender.Window.FileSelector(import_p_follow, 'Import')
		else:
			Blender.Window.FileSelector(import_pdb, 'Import')
	elif evt == 3:
		structmode = "balls"
		scatom.val = 1.0
		sumatom.val = 0.4
		refineballs.val = 24
		balls = 1
		sticks = 0
		bbut.val = 1
		sbbut.val = 0
		sbut.val = 0
		pbut.val = 0
		Redraw()
	elif evt == 4:
		structmode = "sticks and balls"
		scatom.val = 0.75
		sumatom.val = 0.0
		refineballs.val = 20
		refinesticks.val = 12
		balls = 1
		scsticks.val = 0.16
		sticks = 1
		bbut.val = 0
		sbbut.val = 1
		sbut.val = 0
		pbut.val = 0
		Redraw()
	elif evt == 5:
		structmode = "sticks"
		scsticks.val = 0.24
		refinesticks.val = 12
		balls = 0
		sticks = 1
		bbut.val = 0
		sbbut.val = 0
		sbut.val = 1
		pbut.val = 0
		Redraw()
	elif evt == 12:
		structmode = "Backbone"
		scsticks.val = 1.00
		refinesticks.val = 8
		balls = 0
		sticks = 1
		bbut.val = 0
		sbbut.val = 0
		sbut.val = 0
		pbut.val = 1
		Redraw()
	elif evt == 11: 
		if hydros: hydros = 0
		else: hydros = 1
		Redraw()
	elif evt == 8:
		while not ((int(360/refineballs.val) == float(360.00/refineballs.val)) and (int(refineballs.val)/2) == (float(refineballs.val)/2)):
			refineballs.val = refineballs.val + 1
		Redraw()
	elif evt == 10:
		while not ((int(360/refinesticks.val) == float(360.00/refinesticks.val)) and (int(refinesticks.val)/2) == (float(refinesticks.val)/2)):
			refinesticks.val = refinesticks.val + 1
		Redraw()
	
def initialize():
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks, hydros, bbut, sbbut, sbut, pbut
	structmode = Create("balls")
	scatom = Create(1.0)
	sumatom = Create(0.4)
	scsticks = Create(0.24)
	refineballs = Create(24)
	refinesticks = Create(12)
	balls = Create(1)
	sticks = Create(0)
	hydros = Create(1)
	bbut = Create(1)
	sbbut = Create(0)
	sbut = Create(0)
	pbut = Create(0)
	Register(gui, event, bevent)

initialize()

Blender.Redraw()