Skip to content
Snippets Groups Projects
Commit 71413af9 authored by Campbell Barton's avatar Campbell Barton
Browse files

script [#23566] Import: PDB Chemical Files

by Mariusz Maximus & Jong89
parent 1e511dd5
No related branches found
No related tags found
No related merge requests found
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
bl_info = {
"name": "Import/Export: PDB format",
"author": "Mariusz Maximus & Jong89",
"version": (0, 9, 0),
"blender": (2, 6, 0),
"api": 35616,
"location": "File > Import/Export > PDB",
"description": "Import PDB files",
"warning": "",
"wiki_url": "http://blenderartists.org/forum/showthread.php?t=194336",
"tracker_url": "http://blenderartists.org/forum/showthread.php?t=194336",
"category": "Import-Export"}
# @todo write the wiki page
# To support reload properly, try to access a package var,
# if it's there, reload everything
if "bpy" in locals():
import imp
if "import_pdb" in locals():
imp.reload(import_pdb)
import bpy
from bpy.props import (StringProperty,
BoolProperty,
IntProperty,
FloatProperty,
)
from bpy_extras.io_utils import ImportHelper
class ImportPDB(bpy.types.Operator, ImportHelper):
"""Import from PDB file format (.pdb)"""
bl_idname = 'import_scene.pdb'
bl_label = 'Import PDB'
bl_options= {'REGISTER', 'UNDO'}
filename_ext = ".pdb"
filter_glob = StringProperty(default="*.pdb", options={'HIDDEN'})
filepath = StringProperty(
name="File Path",
description="Filepath used for importing the PDB file",
maxlen= 1024,
)
multi_models = BoolProperty(
name="Import all models",
description="Import all alternative structures listed in file",
default=False,
)
multimers = BoolProperty(
name="Import Biomolecules",
description="Import all file-listed biomolecules and multimers, "
"disable to import default biomolecule with all chains",
default=False,
)
retain_alts = BoolProperty(
name="Retain Alternative Atoms",
description="Select to retain alternative atoms. "
"Some PDB files label coordinates of entries "
"in multiple models as alternates" ,
default=False,
)
atom_subdivisions = IntProperty(
name="Atom Subdivisions",
description="Number of icosphere subdivisions for the atoms",
min=1, max=6,
default=3,
)
atom_size = FloatProperty(
name="Atom Size",
description="Multiplier for the van der Waals radius of the atoms",
min=0, max=5,
default=1,
)
scene_scale = FloatProperty(
name="Scene Scale Factor",
description="Number of Blender units equivalent to 1 angstrom",
min=0, max=10,
default=1,
)
def execute(self, context):
from . import import_pdb
import_pdb.load_pdb(self.filepath, context,
self.atom_size,
self.scene_scale,
self.atom_subdivisions,
self.retain_alts,
self.multi_models,
self.multimers)
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
wm.fileselect_add(self)
return {'RUNNING_MODAL'}
def menu_func(self, context):
self.layout.operator(ImportPDB.bl_idname, text='Protein Databank (.pdb)')
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_file_import.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_import.remove(menu_func)
if __name__ == '__main__':
register()
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
import bpy
class Element:
'''Element class with properties ([R, G, B], cov_radius, vdw_radius, name)'''
def __init__(self, color, cov_radius, vdw_radius, name):
self.color = color
self.cov_radius = cov_radius
self.vdw_radius = vdw_radius
self.name = name
class Atom:
'''Atom class with properties (serial, name, altloc, resname,chainid,
resseq, icode, x, y, z, occupancy, tempfactor, element, charge)'''
def __init__(self, serial, name, altloc, resname, chainid, resseq, icode,
x, y, z, occupancy, tempfactor, element, charge):
self.serial = serial
self.name = name
self.altloc = altloc
self.resname = resname
self.chainid = chainid
self.resseq = resseq
self.icode = icode
self.x = x
self.y = y
self.z = z
self.occupancy = occupancy
self.tempfactor = tempfactor
self.element = element
self.charge = charge
#collection of biomolecules based on model
#all chains in model stored here
class Model:
'''Model class'''
def __init__(self, model_id):
self.model_id = model_id
self.atoms = {}
self.atom_count = 0
self.vert_list = []
#Dictionary of {vert index: [list of vertex groups it belongs to]}
#Now element only
self.vert_group_index = {}
#Dictionary of {vertex group: number of group members}
self.vert_group_counts = {}
self.chains = {}
#new object level class
class Biomolecule:
'''Biomolecule'''
def __init__(self, serial):
self.serial = serial
self.atom_count = 0
self.vert_list = []
self.vert_group_index = {}
self.vert_group_counts = {}
self.chain_transforms = {}
#Atom collection
class Chain:
'''Chain'''
def __init__(self, chain_id):
self.chain_id = chain_id
self.atoms = {}
#Atomic data from http://www.ccdc.cam.ac.uk/products/csd/radii/
#Color palatte adapted from Jmol
#"Element symbol":[[Red, Green, Blue], Covalent radius, van der Waals radius,
# Element name]
#Atomic radii are in angstroms (100 pm)
#Unknown covalent radii are assigned 1.5 A, unknown van der Waals radiii are
#assigned 2 A,
atom_data = {
'H' : Element([1.00000, 1.00000, 1.00000], 0.23, 1.09, 'Hydrogen' ),
'HE': Element([0.85098, 1.00000, 1.00000], 1.5 , 1.4 , 'Helium' ),
'LI': Element([0.80000, 0.50196, 1.00000], 1.28, 1.82, 'Lithium' ),
'BE': Element([0.76078, 1.00000, 0.00000], 0.96, 2 , 'Beryllium' ),
'B' : Element([1.00000, 0.70980, 0.70980], 0.83, 2 , 'Boron' ),
'C' : Element([0.56471, 0.56471, 0.56471], 0.68, 1.7 , 'Carbon' ),
'N' : Element([0.18824, 0.31373, 0.97255], 0.68, 1.55, 'Nitrogen' ),
'O' : Element([1.00000, 0.05098, 0.05098], 0.68, 1.52, 'Oxygen' ),
'F' : Element([0.56471, 0.87843, 0.31373], 0.64, 1.47, 'Fluorine' ),
'NE': Element([0.70196, 0.89020, 0.96078], 1.5 , 1.54, 'Neon' ),
'NA': Element([0.67059, 0.36078, 0.94902], 1.66, 2.27, 'Sodium' ),
'MG': Element([0.54118, 1.00000, 0.00000], 1.41, 1.73, 'Magnesium' ),
'AL': Element([0.74902, 0.65098, 0.65098], 1.21, 2 , 'Aluminum' ),
'SI': Element([0.94118, 0.78431, 0.62745], 1.2 , 2.1 , 'Silicon' ),
'P' : Element([1.00000, 0.50196, 0.00000], 1.05, 1.8 , 'Phosphorus'),
'S' : Element([1.00000, 1.00000, 0.18824], 1.02, 1.8 , 'Sulfur' ),
'CL': Element([0.12157, 0.94118, 0.12157], 0.99, 1.75, 'Chlorine' ),
'AR': Element([0.50196, 0.81961, 0.89020], 1.51, 1.88, 'Argon' ),
'K' : Element([0.56078, 0.25098, 0.83137], 2.03, 2.75, 'Potassium' ),
'CA': Element([0.23922, 1.00000, 0.00000], 1.76, 2 , 'Calcium' ),
'SC': Element([0.90196, 0.90196, 0.90196], 1.7 , 2 , 'Scandium' ),
'TI': Element([0.74902, 0.76078, 0.78039], 1.6 , 2 , 'Titanium' ),
'V' : Element([0.65098, 0.65098, 0.67059], 1.53, 2 , 'Vanadium' ),
'CR': Element([0.54118, 0.60000, 0.78039], 1.39, 2 , 'Chromium' ),
'MN': Element([0.61176, 0.47843, 0.78039], 1.61, 2 , 'Manganese' ),
'FE': Element([0.87843, 0.40000, 0.20000], 1.52, 2 , 'Iron' ),
'CO': Element([0.94118, 0.56471, 0.62745], 1.26, 2 , 'Cobalt' ),
'NI': Element([0.31373, 0.81569, 0.31373], 1.24, 1.63, 'Nickel' ),
'CU': Element([0.78431, 0.50196, 0.20000], 1.32, 1.4 , 'Copper' ),
'ZN': Element([0.49020, 0.50196, 0.69020], 1.22, 1.39, 'Zinc' ),
'GA': Element([0.76078, 0.56078, 0.56078], 1.22, 1.87, 'Gallium' ),
'GE': Element([0.40000, 0.56078, 0.56078], 1.17, 2 , 'Germanium' ),
'AS': Element([0.74118, 0.50196, 0.89020], 1.21, 1.85, 'Arsenic' ),
'SE': Element([1.00000, 0.63137, 0.00000], 1.22, 1.9 , 'Selenium' ),
'BR': Element([0.65098, 0.16078, 0.16078], 1.21, 1.85, 'Bromine' ),
'KR': Element([0.36078, 0.72157, 0.81961], 1.5 , 2.02, 'Krypton' ),
'RB': Element([0.43922, 0.18039, 0.69020], 2.2 , 2 , 'Rubidium' ),
'SR': Element([0.00000, 1.00000, 0.00000], 1.95, 2 , 'Strontium' ),
'Y' : Element([0.58039, 1.00000, 1.00000], 1.9 , 2 , 'Yttrium' ),
'ZR': Element([0.58039, 0.87843, 0.87843], 1.75, 2 , 'Zirconium' ),
'NB': Element([0.45098, 0.76078, 0.78824], 1.64, 2 , 'Niobium' ),
'MO': Element([0.32941, 0.70980, 0.70980], 1.54, 2 , 'Molybdenum'),
'TC': Element([0.23137, 0.61961, 0.61961], 1.47, 2 , 'Technetium'),
'RU': Element([0.14118, 0.56078, 0.56078], 1.46, 2 , 'Ruthenium' ),
'RH': Element([0.03922, 0.49020, 0.54902], 1.45, 2 , 'Rhodium' ),
'PD': Element([0.00000, 0.41176, 0.52157], 1.39, 1.63, 'Palladium' ),
'AG': Element([0.75294, 0.75294, 0.75294], 1.45, 1.72, 'Silver' ),
'CD': Element([1.00000, 0.85098, 0.56078], 1.44, 1.58, 'Cadmium' ),
'IN': Element([0.65098, 0.45882, 0.45098], 1.42, 1.93, 'Indium' ),
'SN': Element([0.40000, 0.50196, 0.50196], 1.39, 2.17, 'Tin' ),
'SB': Element([0.61961, 0.38824, 0.70980], 1.39, 2 , 'Antimony' ),
'TE': Element([0.83137, 0.47843, 0.00000], 1.47, 2.06, 'Tellurium' ),
'I' : Element([0.58039, 0.00000, 0.58039], 1.4 , 1.98, 'Iodine' ),
'XE': Element([0.25882, 0.61961, 0.69020], 1.5 , 2.16, 'Xenon' ),
'CS': Element([0.34118, 0.09020, 0.56078], 2.44, 2 , 'Cesium' ),
'BA': Element([0.00000, 0.78824, 0.00000], 2.15, 2 , 'Barium' ),
'LA': Element([0.43922, 0.83137, 1.00000], 2.07, 2 , 'Lanthanum' ),
'CE': Element([1.00000, 1.00000, 0.78039], 2.04, 2 , 'Cerium' ),
'PR': Element([0.85098, 1.00000, 0.78039], 2.03, 2 , 'Praseodymium'),
'ND': Element([0.78039, 1.00000, 0.78039], 2.01, 2 , 'Neodymium' ),
'PM': Element([0.63922, 1.00000, 0.78039], 1.99, 2 , 'Promethium'),
'SM': Element([0.56078, 1.00000, 0.78039], 1.98, 2 , 'Samarium' ),
'EE': Element([0.38039, 1.00000, 0.78039], 1.98, 2 , 'Europium' ),
'GD': Element([0.27059, 1.00000, 0.78039], 1.96, 2 , 'Gadolinium'),
'TB': Element([0.18824, 1.00000, 0.78039], 1.94, 2 , 'Terbium' ),
'DY': Element([0.12157, 1.00000, 0.78039], 1.92, 2 , 'Dysprosium'),
'HO': Element([0.00000, 1.00000, 0.61176], 1.92, 2 , 'Holmium' ),
'ER': Element([0.00000, 0.90196, 0.45882], 1.89, 2 , 'Erbium' ),
'TM': Element([0.00000, 0.83137, 0.32157], 1.9 , 2 , 'Thulium' ),
'YB': Element([0.00000, 0.74902, 0.21961], 1.87, 2 , 'Ytterbium' ),
'LU': Element([0.00000, 0.67059, 0.14118], 1.87, 2 , 'Lutetium' ),
'HF': Element([0.30196, 0.76078, 1.00000], 1.75, 2 , 'Hafnium' ),
'TA': Element([0.30196, 0.65098, 1.00000], 1.7 , 2 , 'Tantalum' ),
'W' : Element([0.12941, 0.58039, 0.83922], 1.62, 2 , 'Tungsten' ),
'RE': Element([0.14902, 0.49020, 0.67059], 1.51, 2 , 'Rhenium' ),
'OS': Element([0.14902, 0.40000, 0.58824], 1.44, 2 , 'Osmium' ),
'IR': Element([0.09020, 0.32941, 0.52941], 1.41, 2 , 'Iridium' ),
'PT': Element([0.81569, 0.81569, 0.87843], 1.36, 1.72, 'Platinum' ),
'AU': Element([1.00000, 0.81961, 0.13725], 1.5 , 1.66, 'Gold' ),
'HG': Element([0.72157, 0.72157, 0.81569], 1.32, 1.55, 'Mercury' ),
'TL': Element([0.65098, 0.32941, 0.30196], 1.45, 1.96, 'Thallium' ),
'PB': Element([0.34118, 0.34902, 0.38039], 1.46, 2.02, 'Lead' ),
'BI': Element([0.61961, 0.30980, 0.70980], 1.48, 2 , 'Bismuth' ),
'PO': Element([0.67059, 0.36078, 0.00000], 1.4 , 2 , 'Polonium' ),
'AT': Element([0.45882, 0.30980, 0.27059], 1.21, 2 , 'Astatine' ),
'RN': Element([0.25882, 0.50980, 0.58824], 1.5 , 2 , 'Radon' ),
'FR': Element([0.25882, 0.00000, 0.40000], 2.6 , 2 , 'Francium' ),
'RA': Element([0.00000, 0.49020, 0.00000], 2.21, 2 , 'Radium' ),
'AC': Element([0.43922, 0.67059, 0.98039], 2.15, 2 , 'Actinium' ),
'TH': Element([0.00000, 0.72941, 1.00000], 2.06, 2 , 'Thorium' ),
'PA': Element([0.00000, 0.63137, 1.00000], 2 , 2 , 'Protactinium'),
'U' : Element([0.00000, 0.56078, 1.00000], 1.96, 1.86, 'Uranium' ),
'NP': Element([0.00000, 0.50196, 1.00000], 1.9 , 2 , 'Neptunium' ),
'PU': Element([0.00000, 0.41961, 1.00000], 1.87, 2 , 'Plutonium' ),
'AM': Element([0.32941, 0.36078, 0.94902], 1.8 , 2 , 'Americium' ),
'CM': Element([0.47059, 0.36078, 0.89020], 1.69, 2 , 'Curium' ),
'BK': Element([0.54118, 0.30980, 0.89020], 1.54, 2 , 'Berkelium' ),
'CF': Element([0.63137, 0.21176, 0.83137], 1.83, 2 , 'Californium'),
'ES': Element([0.70196, 0.12157, 0.83137], 1.5 , 2 , 'Einsteinium'),
'FM': Element([0.70196, 0.12157, 0.72941], 1.5 , 2 , 'Fermium' ),
'MD': Element([0.70196, 0.05098, 0.65098], 1.5 , 2 , 'Mendelevium'),
'NO': Element([0.74118, 0.05098, 0.52941], 1.5 , 2 , 'Nobelium' ),
'LR': Element([0.78039, 0.00000, 0.40000], 1.5 , 2 , 'Lawrencium'),
'RF': Element([0.80000, 0.00000, 0.34902], 1.5 , 2 , 'Rutherfordium'),
'DB': Element([0.81961, 0.00000, 0.30980], 1.5 , 2 , 'Dubnium' ),
'SG': Element([0.85098, 0.00000, 0.27059], 1.5 , 2 , 'Seaborgium'),
'BH': Element([0.87843, 0.00000, 0.21961], 1.5 , 2 , 'Bohrium' ),
'HS': Element([0.90196, 0.00000, 0.18039], 1.5 , 2 , 'Hassium' ),
'MT': Element([0.92157, 0.00000, 0.14902], 1.5 , 2 , 'Meitnerium'),
'DS': Element([0.93725, 0.00000, 0.12157], 1.5 , 2 , 'Darmstadtium')
}
def load_pdb(filepath, context, atom_size, scene_scale, atom_subdivisions,
retain_alts, multi_models, multimers):
file = open(filepath, 'r')
lines = file.readlines()
file.close()
model_list = {}
model_flag = False
biomolecule_flag = False
biomolecule_list = {}
chain_list = []
mat_list = []
#Parse data
for line in lines:
# print(line)
if line[:6] == 'COMPND':
if line[11:17] == 'CHAIN:':
s = 17
for i in range(1, (len(line[17:]) + 1)):
if line[16+i:17+i] == ',':
chain_id = line[s:16+i].strip()
chain_list.append(chain_id)
s = 17 + i
elif line[16+i:17+i] == ';':
chain_id = line[s:16+i].strip()
chain_list.append(chain_id)
break
elif i == len(line[17:]):
chain_id = line[s:].strip()
chain_list.append(chain_id)
elif line[:10] == 'REMARK 300':
if line[11:23] == 'BIOMOLECULE:':
biomolecule_flag = True
s = 23
for i in range(1, (len(line[23:]) + 1)):
if line[22+i:23+i] == ',':
bm_serial = int(line[s:22+i])
biomolecule_list[bm_serial] = Biomolecule(bm_serial)
s = 23 + i
elif i == len(line[23:]):
bm_serial = int(line[s:])
biomolecule_list[bm_serial] = Biomolecule(bm_serial)
elif line[:10] == 'REMARK 350':
if line[11:23] == 'BIOMOLECULE:':
cur_biomolecule = biomolecule_list[int(line[23:].strip())]
elif line[11:41] == 'APPLY THE FOLLOWING TO CHAINS:':
s = 41
cur_chain_list = []
for i in range(1, (len(line[41:]) + 1)):
if line[40+i:41+i] == ',':
cur_chain_list.append(line[s:40+i].strip())
s = 41+i
elif i == len(line[41:]):
cur_chain_list.append(line[s:].strip())
cur_biomolecule.chain_transforms[tuple(cur_chain_list)] = []
elif line[13:18] == 'BIOMT':
if line[18:19] == '1':
row1 = [float(line[24:33]), float(line[34:43]),
float(line[44:53]), float(line[60:68])]
elif line[18:19] == '2':
row2 =[float(line[24:33]), float(line[34:43]),
float(line[44:53]), float(line[60:68])]
elif line[18:19] == '3':
row3 = [float(line[24:33]), float(line[34:43]),
float(line[44:53]), float(line[60:68])]
cur_biomolecule.chain_transforms[tuple(cur_chain_list)].append([row1, row2, row3])
elif line[:5] == 'MODEL':
model_id = int(line[10:14])
model_list[model_id] = Model(model_id)
cur_model = model_list[model_id]
model_flag = True
for chain in chain_list:
cur_model.chains[chain] = Chain(chain)
elif line[:6] == 'ENDMDL':
cur_model = None
elif line[:4] == 'ATOM':
if not model_flag:
model_list[1] = Model(1)
cur_model = model_list[1]
model_flag = True
for chain in chain_list:
cur_model.chains[chain] = Chain(chain)
serial = int(line[6:11])
name = line[12:16].strip()
altloc = line[16:17]
resname = line[17:20]
chainid = line[21:22]
resseq = int(line[22:26])
icode = line[26:28].strip()
x = float(line[30:38]) * scene_scale
y = float(line[38:46]) * scene_scale
z = float(line[46:54]) * scene_scale
occupancy = float(line[54:60])
tempfactor = float(line[60:66])
element = line[76:78].strip()
charge = line[78:80].strip()
'''print('******************************************************************')
print('serial : ' )
print(serial)
print('name : ' )
print(name)
print('altloc : ' )
print(altloc)
print('resname : ' )
print(resname)
print('chainid : ' )
print(chainid)
print('resseq : ' )
print(resseq)
print('icode : ' )
print(icode)
print('x : ' )
print(x)
print('y : ' )
print(y)
print('z : ' )
print(z)
print('occupancy : ' )
print(occupancy)
print('tempfactor : ' )
print(tempfactor)
print('element : ' )
print(element)
print('charge : ' )
print(charge)
print('******************************************************************')'''
cur_model.chains[chainid].atoms[serial] = Atom(serial, name, altloc,
resname, chainid,
resseq, icode,
x, y, z, occupancy,
tempfactor, element,
charge)
if (not multimers) or (not biomolecule_flag):
#Create a default biomolecule w/ all chains and identity transform
#Overwrites original biomolecule_list
biomolecule_flag = True
biomolecule_list = {1:Biomolecule(1)}
biomolecule_list[1].chain_transforms[tuple(chain_list)] = []
biomolecule_list[1].chain_transforms[tuple(chain_list)].append([[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0]])
#Create atom mesh template
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=atom_subdivisions,
size=(atom_size * scene_scale))
bpy.ops.object.shade_smooth()
atom_mesh = bpy.context.active_object.data
atom_mesh.name = 'Atom_Template'
bpy.ops.object.delete()
layers = bpy.context.scene.layers
#After parsing and preparing the templates, generate the output
for model_id, model in model_list.items():
if (not multi_models) and model_id != 1:
break
for bm_serial, biomolecule in biomolecule_list.items():
biom_mesh = bpy.data.meshes.new('Biomolecule' + str(bm_serial) + '.' +
str(model_id))
cur_biom = bpy.data.objects.new('Biomolecule' + str(bm_serial) +
'.' + str(model_id), biom_mesh)
bpy.context.scene.objects.link(cur_biom)
for chain_clones, transforms in biomolecule.chain_transforms.items():
for chain in chain_clones:
for transform in transforms:
#rotations
row1 = transform[0][0:3]
row2 = transform[1][0:3]
row3 = transform[2][0:3]
#translations
dx = transform[0][3]
dy = transform[1][3]
dz = transform[2][3]
for serial, atom in model.chains[chain].atoms.items():
#Prunes alternative locations for the atoms
#(should pick the one with highest occupancy but doesn't)
if (atom.altloc == ' ' or atom.altloc == 'A') or retain_alts:
element = atom_data[atom.element].name
#Generate master element models
if element not in mat_list:
#Create a master atom
mesh = atom_mesh.copy()
mesh.name = element
mat = bpy.data.materials.new(element)
mat.diffuse_color = atom_data[atom.element].color
mesh.materials.append(mat)
master_atom = bpy.data.objects.new(element, mesh)
master_atom.scale = [atom_data[atom.element].vdw_radius]*3
master_atom.layers = layers
master_atom.name = element
bpy.context.scene.objects.link(master_atom)
mat_list.append(element)
else:
pass
#Generate element vertex groups
if element not in cur_biom.vertex_groups:
cur_vert_group = cur_biom.vertex_groups.new(element)
#Adds a key in the vert_group_count
biomolecule.vert_group_counts[cur_vert_group] = 0
else:
cur_vert_group = cur_biom.vertex_groups[element]
#Generate particle systems (can be merged with vertex group generator)
if element not in cur_biom.particle_systems:
bpy.context.scene.objects.active = cur_biom
bpy.ops.object.particle_system_add()
cur_particle = cur_biom.particle_systems.active
cur_particle.name = element
cur_particle.settings.name = (element + '.' + str(bm_serial) + '.' + str(model_id))
cur_particle.settings.frame_start = 0
cur_particle.settings.frame_end = 0
cur_particle.settings.lifetime = 10000
cur_particle.settings.emit_from = 'VERT'
cur_particle.settings.use_emit_random = False
cur_particle.settings.normal_factor = 0
cur_particle.settings.particle_size = 1
cur_particle.settings.render_type = 'OBJECT'
cur_particle.settings.dupli_object = bpy.data.objects[element]
cur_particle.settings.effector_weights.gravity = 0
cur_particle.vertex_group_density = element
biomolecule.vert_group_index[biomolecule.atom_count] = cur_vert_group
biomolecule.vert_group_counts[cur_vert_group] += 1
biomolecule.atom_count += 1
tx = atom.x * row1[0] + atom.y * row1[1] + atom.z * row1[2] + (dx * scene_scale)
ty = atom.x * row2[0] + atom.y * row2[1] + atom.z * row2[2] + (dy * scene_scale)
tz = atom.x * row3[0] + atom.y * row3[1] + atom.z * row3[2] + (dz * scene_scale)
biomolecule.vert_list.extend([tx, ty, tz])
else:
pass
biom_mesh.vertices.add(biomolecule.atom_count)
biom_mesh.vertices.foreach_set('co', biomolecule.vert_list)
for vert_index, vert_group in biomolecule.vert_group_index.items():
aa = [] # neeed array to vertex_groups.assign
aa.append(vert_index)
vert_group.add(aa, 1, "ADD")
for vert_group, count in biomolecule.vert_group_counts.items():
bpy.data.particles[vert_group.name + '.' + str(bm_serial) + '.' + str(model_id)].count = count
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment