diff --git a/io_mesh_pdb/__init__.py b/io_mesh_pdb/__init__.py index 14b556f5e9c544643fcee18bfde5174455c3d1ad..3a479dbd1e4504b799a4eb03eaec0726b54cc232 100644 --- a/io_mesh_pdb/__init__.py +++ b/io_mesh_pdb/__init__.py @@ -42,12 +42,9 @@ from bpy.props import (StringProperty, IntProperty, FloatProperty) - -# TODO, allow reload from . import import_pdb from . import export_pdb - ATOM_PDB_ERROR = "" ATOM_PDB_PANEL = "" @@ -230,7 +227,7 @@ class CLASS_atom_pdb_Properties(bpy.types.PropertyGroup): name = "Radius", default=0.1, min=0.0001, description ="Radius of a stick") sticks_unit_length = FloatProperty( - name = "Unit", default=0.2, min=0.0001, + name = "Unit", default=0.05, min=0.0001, description = "Length of the unit of a stick in Angstrom") use_sticks_color = BoolProperty( name="Color", default=True, @@ -303,22 +300,6 @@ class CLASS_atom_pdb_datafile_apply(Operator): import_pdb.DEF_atom_pdb_custom_datafile(scn.datafile) - # TODO, move this into 'import_pdb' and call the function - for obj in bpy.context.selected_objects: - if len(obj.children) != 0: - child = obj.children[0] - if child.type == "SURFACE" or child.type == "MESH": - for element in import_pdb.ATOM_PDB_ELEMENTS: - if element.name in obj.name: - child.scale = (element.radii[0],) * 3 - child.active_material.diffuse_color = element.color - else: - if obj.type == "SURFACE" or obj.type == "MESH": - for element in import_pdb.ATOM_PDB_ELEMENTS: - if element.name in obj.name: - obj.scale = (element.radii[0],) * 3 - obj.active_material.diffuse_color = element.color - return {'FINISHED'} @@ -350,7 +331,7 @@ class CLASS_atom_pdb_separate_atom(Operator): # ... delete the new mesh including the separated vertex bpy.ops.object.select_all(action='DESELECT') new_object.select = True - bpy.ops.object.delete() # TODO, use scene.objects.unlink() + bpy.ops.object.delete() # Create a new atom/vacancy at the position of the old atom current_layers=bpy.context.scene.layers @@ -426,8 +407,7 @@ class CLASS_atom_pdb_radius_all_bigger_button(Operator): scn = bpy.context.scene.atom_pdb[0] import_pdb.DEF_atom_pdb_radius_all( scn.radius_all, - scn.radius_how, - ) + scn.radius_how,) return {'FINISHED'} @@ -441,8 +421,7 @@ class CLASS_atom_pdb_radius_all_smaller_button(Operator): scn = bpy.context.scene.atom_pdb[0] import_pdb.DEF_atom_pdb_radius_all( 1.0/scn.radius_all, - scn.radius_how, - ) + scn.radius_how,) return {'FINISHED'} @@ -458,9 +437,8 @@ class CLASS_atom_pdb_radius_sticks_button(Operator): scn = bpy.context.scene.atom_pdb[0] result = import_pdb.DEF_atom_pdb_radius_sticks( - scn.sticks_radius * 0.9, - scn.radius_how,) - + 0.01, + scn.radius_how,) if result == False: ATOM_PDB_ERROR = "No sticks => no changes" bpy.ops.atom_pdb.error_dialog('INVOKE_DEFAULT') @@ -606,7 +584,7 @@ class CLASS_ImportPDB(Operator, ImportHelper): name = "Radius", default=0.1, min=0.0001, description ="Radius of a stick") sticks_unit_length = FloatProperty( - name = "Unit", default=0.2, min=0.0001, + name = "Unit", default=0.05, min=0.0001, description = "Length of the unit of a stick in Angstrom") use_sticks_color = BoolProperty( name="Color", default=True, diff --git a/io_mesh_pdb/export_pdb.py b/io_mesh_pdb/export_pdb.py index 5e17e0bbfc258849c1d65a66bf07eb58e78352c3..e470036109c89d26d7f86d62dc6d327069ba20dd 100644 --- a/io_mesh_pdb/export_pdb.py +++ b/io_mesh_pdb/export_pdb.py @@ -25,7 +25,7 @@ # # Start of project : 2011-08-31 by Clemens Barth # First publication in Blender : 2011-11-11 -# Last modified : 2012-03-22 +# Last modified : 2012-03-23 # # Acknowledgements: Thanks to ideasman, meta_androcto, truman, kilon, # dairin0d, PKHG, Valter, etc @@ -50,8 +50,6 @@ ATOM_PDB_PDBTEXT = ( "REMARK This pdb file has been created with Blender " + "REMARK\n") - - class CLASS_atom_pdb_atoms_export(object): __slots__ = ('element', 'location') def __init__(self, element, location): @@ -59,8 +57,6 @@ class CLASS_atom_pdb_atoms_export(object): self.location = location - - def DEF_atom_pdb_export(obj_type): list_atoms = [] @@ -117,3 +113,4 @@ def DEF_atom_pdb_export(obj_type): pdb_file_p.close() return True + diff --git a/io_mesh_pdb/import_pdb.py b/io_mesh_pdb/import_pdb.py index fa8a92f513eee384e7d68a094d88e54bbdeaa9a9..b4f52af50fc0a2f19554c097e5b5610bcf971dce 100644 --- a/io_mesh_pdb/import_pdb.py +++ b/io_mesh_pdb/import_pdb.py @@ -25,7 +25,7 @@ # # Start of project : 2011-08-31 by Clemens Barth # First publication in Blender : 2011-11-11 -# Last modified : 2012-03-22 +# Last modified : 2012-03-23 # # Acknowledgements: Thanks to ideasman, meta_androcto, truman, kilon, # dairin0d, PKHG, Valter, etc @@ -216,22 +216,18 @@ class CLASS_atom_pdb_stick(object): self.number = number self.dist = dist - # ----------------------------------------------------------------------------- # Some small routines - # Routine which produces a cylinder. All is somewhat easy to undertsand. def DEF_atom_pdb_build_stick(radius, length, sectors): - vertices = [] - faces = [] - dphi = 2.0 * pi/(float(sectors)-1) # Vertices vertices_top = [Vector((0,0,length / 2.0))] vertices_bottom = [Vector((0,0,-length / 2.0))] + vertices = [] for i in range(sectors-1): x = radius * cos( dphi * i ) y = radius * sin( dphi * i ) @@ -243,7 +239,16 @@ def DEF_atom_pdb_build_stick(radius, length, sectors): vertices_bottom.append(vertex) vertices = vertices_top + vertices_bottom + # Side facets (Cylinder) + faces1 = [] + for i in range(sectors-1): + if i == sectors-2: + faces1.append( [i+1, 1, 1+sectors, i+1+sectors] ) + else: + faces1.append( [i+1, i+2, i+2+sectors, i+1+sectors] ) + # Top facets + faces2 = [] for i in range(sectors-1): if i == sectors-2: face_top = [0,sectors-1,1] @@ -254,28 +259,27 @@ def DEF_atom_pdb_build_stick(radius, length, sectors): for j in range(2): face_top.append(i+j+1) face_bottom.append(i+j+1+sectors) - faces.append(face_top) - faces.append(face_bottom) - - # Side facets - for i in range(sectors-1): - if i == sectors-2: - faces.append( [i+1, 1, 1+sectors, i+1+sectors] ) - else: - faces.append( [i+1, i+2, i+2+sectors, i+1+sectors] ) + faces2.append(face_top) + faces2.append(face_bottom) - # Build the mesh + # Build the mesh, Cylinder cylinder = bpy.data.meshes.new("Sticks_Cylinder") - cylinder.from_pydata(vertices, [], faces) + cylinder.from_pydata(vertices, [], faces1) cylinder.update() new_cylinder = bpy.data.objects.new("Sticks_Cylinder", cylinder) bpy.context.scene.objects.link(new_cylinder) - return new_cylinder + # Build the mesh, Cups + cups = bpy.data.meshes.new("Sticks_Cups") + cups.from_pydata(vertices, [], faces2) + cups.update() + new_cups = bpy.data.objects.new("Sticks_Cups", cups) + bpy.context.scene.objects.link(new_cups) + return (new_cylinder, new_cups) -# This function measures the distance between two objects (atoms), -# which are active. + +# This function measures the distance between two active objects (atoms). def DEF_atom_pdb_distance(): if len(bpy.context.selected_bases) > 1: @@ -495,7 +499,6 @@ def DEF_atom_pdb_radius_sticks(radius, how): return True - # ----------------------------------------------------------------------------- # The custom data file @@ -556,14 +559,27 @@ def DEF_atom_pdb_custom_datafile(path_datafile): ATOM_PDB_ELEMENTS.append(element) data_file_p.close() - + + for obj in bpy.context.selected_objects: + if len(obj.children) != 0: + child = obj.children[0] + if child.type == "SURFACE" or child.type == "MESH": + for element in ATOM_PDB_ELEMENTS: + if element.name in obj.name: + child.scale = (element.radii[0],) * 3 + child.active_material.diffuse_color = element.color + else: + if obj.type == "SURFACE" or obj.type == "MESH": + for element in ATOM_PDB_ELEMENTS: + if element.name in obj.name: + obj.scale = (element.radii[0],) * 3 + obj.active_material.diffuse_color = element.color + return True - # ----------------------------------------------------------------------------- # The main routine - def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, Ball_radius_factor,radiustype,Ball_distance_factor, use_sticks,use_sticks_color,use_sticks_smooth, @@ -602,11 +618,9 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, radii,radii_ionic) ATOM_PDB_ELEMENTS.append(li) - # ------------------------------------------------------------------------ # READING DATA OF ATOMS - if DEF_atom_pdb_custom_datafile(path_datafile): print("Custom data file is loaded.") @@ -738,11 +752,9 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, # From above it can be clearly seen that j is now the number of all atoms. Number_of_total_atoms = j - # ------------------------------------------------------------------------ # MATERIAL PROPERTIES FOR ATOMS - # The list that contains info about all types of atoms is created # here. It is used for building the material properties for # instance (see below). @@ -795,11 +807,9 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, # The atom gets its properties. atom.material = material - # ------------------------------------------------------------------------ # READING DATA OF STICKS - # Open the PDB file again such that the file pointer is in the first # line ... . Stupid, I know ... ;-) ATOM_PDB_FILEPATH_p = io.open(ATOM_PDB_FILEPATH, "r") @@ -829,8 +839,8 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, # The strings of the atom numbers do have a clear position in the file # (From 7 to 12, from 13 to 18 and so on.) and one needs to consider # this. One could also use the split function but then one gets into - # trouble if there are many atoms: For instance, it may happen that one - # has + # trouble if there are lots of atoms: For instance, it may happen that + # one has # CONECT 11111 22244444 # # In Fact it means that atom No. 11111 has a connection with atom @@ -914,11 +924,9 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, ATOM_PDB_FILEPATH_p.close() # So far, all atoms and sticks have been registered. - # ------------------------------------------------------------------------ # TRANSLATION OF THE STRUCTURE TO THE ORIGIN - # It may happen that the structure in a PDB file already has an offset # If chosen, the structure is first put into the center of the scene # (the offset is substracted). @@ -937,20 +945,16 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, for atom in all_atoms: atom.location -= sum_vec - # ------------------------------------------------------------------------ # SCALING - # Take all atoms and adjust their radii and scale the distances. for atom in all_atoms: atom.location *= Ball_distance_factor - # ------------------------------------------------------------------------ # DETERMINATION OF SOME GEOMETRIC PROPERTIES - # In the following, some geometric properties of the whole object are # determined: center, size, etc. sum_vec = Vector((0.0,0.0,0.0)) @@ -968,7 +972,6 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, object_size = 0.0 object_size = max(object_size_vec).length - # ------------------------------------------------------------------------ # CAMERA AND LAMP @@ -1024,14 +1027,6 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, snap_align=False, snap_normal=(0, 0, 0), release_confirm=False) - - # This does not work, I don't know why. - # - #for area in bpy.context.screen.areas: - # if area.type == 'VIEW_3D': - # area.spaces[0].region_3d.view_perspective = 'CAMERA' - - # Here a lamp is put into the scene, if chosen. if use_lamp == True: @@ -1063,11 +1058,9 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, bpy.context.scene.world.light_settings.use_ambient_occlusion = True bpy.context.scene.world.light_settings.ao_factor = 0.2 - # ------------------------------------------------------------------------ # SOME OUTPUT ON THE CONSOLE - print() print() print() @@ -1079,11 +1072,9 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, print("Size of object (Angstrom) : ", object_size) print() - # ------------------------------------------------------------------------ # SORTING THE ATOMS - # Lists of atoms of one type are created. Example: # draw_all_atoms = [ data_hydrogen,data_carbon,data_nitrogen ] # data_hydrogen = [["Hydrogen", Material_Hydrogen, Vector((x,y,z)), 109], ...] @@ -1116,11 +1107,9 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, # Now append the atom list to the list of all types of atoms draw_all_atoms.append(draw_all_atoms_type) - # ------------------------------------------------------------------------ # DRAWING THE ATOMS - # This is the number of all atoms which are put into the scene. bpy.ops.object.select_all(action='DESELECT') @@ -1183,7 +1172,6 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, print() - # ------------------------------------------------------------------------ # DRAWING THE STICKS @@ -1280,7 +1268,6 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, sticks_all_lists.append(sticks_list) - # ... the sticks in the list can be drawn: for stick_list in sticks_all_lists: vertices = [] @@ -1324,19 +1311,23 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, bpy.context.scene.objects.link(new_mesh) current_layers = bpy.context.scene.layers - stick_cylinder = DEF_atom_pdb_build_stick(Stick_diameter, dl, Stick_sectors) + object_stick = DEF_atom_pdb_build_stick(Stick_diameter, dl, Stick_sectors) + stick_cylinder = object_stick[0] stick_cylinder.active_material = stick[3] - + stick_cups = object_stick[1] + stick_cups.active_material = stick[3] + if use_sticks_smooth == True: - for face in stick_cylinder.data.faces: - face.use_smooth = True + bpy.ops.object.select_all(action='DESELECT') + stick_cylinder.select = True + stick_cups.select = True + bpy.ops.object.shade_smooth() stick_cylinder.parent = new_mesh + stick_cups.parent = new_mesh new_mesh.dupli_type = 'FACES' atom_object_list.append(new_mesh) - - # ------------------------------------------------------------------------ # SELECT ALL LOADED OBJECTS bpy.ops.object.select_all(action='DESELECT') @@ -1351,5 +1342,4 @@ def DEF_atom_pdb_main(use_mesh,Ball_azimuth,Ball_zenith, print("\n\nAll atoms (%d) and sticks (%d) have been drawn - finished.\n\n" % (Number_of_total_atoms,Number_of_sticks)) - return Number_of_total_atoms