[Bf-extensions-cvs] [850dfa2a] master: Concept change: massive use of the collection principle to well structure atoms and sticks of the molecule

Clemens Barth noreply at git.blender.org
Sun Mar 17 17:22:29 CET 2019


Commit: 850dfa2aa0549eb6c556b302b897aaa225dd55ca
Author: Clemens Barth
Date:   Sun Mar 17 17:12:29 2019 +0100
Branches: master
https://developer.blender.org/rBA850dfa2aa0549eb6c556b302b897aaa225dd55ca

Concept change: massive use of the collection principle to well structure atoms and sticks of the molecule

Thanks to the great concept of 'collections', which Blender 2.80 is proposing, all parts of
the molecule (atoms and sticks) can be organized in an hierarchical order in dependence
on the chemical elements. Atoms (balls) are further separated from sticks (cylinders). For
some molecules, I tested all possible properties one can chose during the import, and it
works very well.

===================================================================

M	io_mesh_pdb/import_pdb.py

===================================================================

diff --git a/io_mesh_pdb/import_pdb.py b/io_mesh_pdb/import_pdb.py
index 5c3f2775..dd2f4c80 100644
--- a/io_mesh_pdb/import_pdb.py
+++ b/io_mesh_pdb/import_pdb.py
@@ -16,6 +16,7 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+import os
 import bpy
 import bmesh
 from math import pi, cos, sin, sqrt, ceil
@@ -529,15 +530,17 @@ def build_stick(radius, length, sectors, element_name):
     cylinder.from_pydata(vertices, [], faces1)
     cylinder.update()
     new_cylinder = bpy.data.objects.new(element_name+"_sticks_cylinder", cylinder)
-    bpy.context.collection.objects.link(new_cylinder)
+    # Attention: the linking will be done a few moments later, after this 
+    # is done definition.
 
     # Build the mesh, Cups
     cups = bpy.data.meshes.new(element_name+"_sticks_cup")
     cups.from_pydata(vertices, [], faces2)
     cups.update()
     new_cups = bpy.data.objects.new(element_name+"_sticks_cup", cups)
-    bpy.context.collection.objects.link(new_cups)
-
+    # Attention: the linking will be done a few moments later, after this 
+    # is done definition.
+    
     return (new_cylinder, new_cups)
 
 
@@ -635,10 +638,10 @@ def draw_atoms_one_type(draw_all_atoms_type,
                         Ball_azimuth,
                         Ball_zenith,
                         Ball_radius_factor,
-                        object_center_vec):
+                        object_center_vec,
+                        collection_molecule):
 
-    # Create first the vertices composed of the coordinates of all
-    # atoms of one type
+    # Create the vertices composed of the coordinates of all atoms of one type
     atom_vertices = []
     for atom in draw_all_atoms_type:
         # In fact, the object is created in the World's origin.
@@ -646,15 +649,35 @@ def draw_atoms_one_type(draw_all_atoms_type,
         # the whole object is translated back to 'object_center_vec'.
         atom_vertices.append(atom[2] - object_center_vec)
 
+    # IMPORTANT: First, we create a collection of the element, which contains 
+    # the atoms (balls + mesh) AND the sticks! The definition dealing with the
+    # sticks will put the sticks inside this collection later on. 
+    coll_element_name = atom[0] # the element name
+    # Create the new collection and ...
+    coll_element = bpy.data.collections.new(coll_element_name)
+    # ... link it to the collection, which contains all parts of the 
+    # molecule.
+    collection_molecule.children.link(coll_element)
+
+    # Now, create a collection for the atoms, which includes the representative
+    # ball and the mesh.
+    coll_atom_name = atom[0] + "_atom"
+    # Create the new collection and ...
+    coll_atom = bpy.data.collections.new(coll_atom_name)
+    # ... link it to the collection, which contains all parts of the 
+    # element (ball and mesh).
+    coll_element.children.link(coll_atom)
+
     # Build the mesh
     atom_mesh = bpy.data.meshes.new("Mesh_"+atom[0])
     atom_mesh.from_pydata(atom_vertices, [], [])
     atom_mesh.update()
     new_atom_mesh = bpy.data.objects.new(atom[0] + "_mesh", atom_mesh)
-    bpy.context.collection.objects.link(new_atom_mesh)
 
-    # Now, build a representative sphere (atom).
+    # Link active object to the new collection
+    coll_atom.objects.link(new_atom_mesh)
 
+    # Now, build a representative sphere (atom).
     if atom[0] == "Vacancy":
         bpy.ops.mesh.primitive_cube_add(
                         view_align=False, enter_editmode=False,
@@ -685,13 +708,26 @@ def draw_atoms_one_type(draw_all_atoms_type,
         ball.name = atom[0] + "_cube"
     else:
         ball.name = atom[0] + "_ball" 
+
     ball.active_material = atom[1]
     ball.parent = new_atom_mesh
     new_atom_mesh.instance_type = 'VERTS'
     # The object is back translated to 'object_center_vec'.
     new_atom_mesh.location = object_center_vec
 
-    return new_atom_mesh
+    # Note the collection where the ball was placed into.
+    coll_all = ball.users_collection
+    if len(coll_all) > 0:
+        coll_past = coll_all[0]
+    else:
+        coll_past = bpy.context.scene.collection
+
+    # Put the atom into the new collection 'atom' and ...
+    coll_atom.objects.link(ball)
+    # ... unlink the atom from the other collection.
+    coll_past.objects.unlink(ball)
+
+    return new_atom_mesh, coll_element
 
 
 # Function, which draws the sticks with help of the dupliverts technique.
@@ -705,7 +741,8 @@ def draw_sticks_dupliverts(all_atoms,
                            Stick_unit,
                            Stick_dist,
                            use_sticks_smooth,
-                           use_sticks_color):
+                           use_sticks_color,
+                           list_coll_elements):
 
     dl = Stick_unit
 
@@ -834,12 +871,25 @@ def draw_sticks_dupliverts(all_atoms,
                 faces.append((i*4+0,i*4+2,i*4+1,i*4+3))
                 i += 1
 
+        # Create a collection for the sticks, which includes the representative
+        # cylinders, cups and the mesh.
+        coll_name = stick[0][1:] + "_sticks"
+        # Create the collection and ...
+        coll = bpy.data.collections.new(coll_name)
+        # ... link it to the collection, which contains all parts of the 
+        # element. 'stick[0][1:]' contains the name of the element!
+        for coll_element_from_list in list_coll_elements:
+            if stick[0][1:] in coll_element_from_list.name:
+                break
+        coll_element_from_list.children.link(coll)
+
         # Build the mesh.
         mesh = bpy.data.meshes.new("Sticks_"+stick[0][1:])
         mesh.from_pydata(vertices, [], faces)
         mesh.update()
         new_mesh = bpy.data.objects.new(stick[0][1:]+"_sticks_mesh", mesh)
-        bpy.context.collection.objects.link(new_mesh)
+        # Link active object to the new collection
+        coll.objects.link(new_mesh)
 
         # Build the object.
         # Get the cylinder from the 'build_stick' function.
@@ -847,11 +897,15 @@ def draw_sticks_dupliverts(all_atoms,
                                    dl, 
                                    Stick_sectors, 
                                    stick[0][1:])
+        # Link active object to the new collection
+        coll.objects.link(object_stick[0])
+        coll.objects.link(object_stick[1])
+
         stick_cylinder = object_stick[0]
         stick_cylinder.active_material = stick[3]
         stick_cups = object_stick[1]
         stick_cups.active_material = stick[3]
-
+    
         # Smooth the cylinders.
         if use_sticks_smooth == True:
             bpy.ops.object.select_all(action='DESELECT')
@@ -877,7 +931,8 @@ def draw_sticks_skin(all_atoms,
                      Stick_diameter,
                      use_sticks_smooth,
                      sticks_subdiv_view,
-                     sticks_subdiv_render):
+                     sticks_subdiv_render,
+                     coll_molecule):
 
     # These counters are for the edges, in the shape [i,i+1].
     i = 0
@@ -962,7 +1017,8 @@ def draw_sticks_skin(all_atoms,
     stick_mesh.from_pydata(stick_vertices, stick_edges, [])
     stick_mesh.update()
     new_stick_mesh = bpy.data.objects.new("Sticks", stick_mesh)
-    bpy.context.collection.objects.link(new_stick_mesh)
+    # Link the active mesh to the molecule collection
+    coll_molecule.objects.link(new_stick_mesh)
 
     # Apply the skin modifier.
     new_stick_mesh.modifiers.new(name="Sticks_skin", type='SKIN')
@@ -979,7 +1035,7 @@ def draw_sticks_skin(all_atoms,
     stick_material.diffuse_color = ELEMENTS[-1].color
     new_stick_mesh.active_material = stick_material
 
-    # This is for putting the radiu of the sticks onto
+    # This is for putting the radius of the sticks onto
     # the desired value 'Stick_diameter'
     bpy.context.view_layer.objects.active = new_stick_mesh
     # EDIT mode
@@ -1025,7 +1081,8 @@ def draw_sticks_normal(all_atoms,
                        Stick_sectors,
                        use_sticks_smooth,
                        use_sticks_one_object,
-                       use_sticks_one_object_nr):
+                       use_sticks_one_object_nr,
+                       coll_molecule):
 
     bpy.ops.object.material_slot_add()
     stick_material = bpy.data.materials.new(ELEMENTS[-1].name)
@@ -1054,14 +1111,14 @@ def draw_sticks_normal(all_atoms,
         # Calculate Euler angles
         euler = Matrix.Rotation(angle, 4, axis).to_euler()
         # Create stick
-        bpy.ops.mesh.primitive_cylinder_add(vertices=Stick_sectors,
-                                            radius=Stick_diameter,
-                                            depth=v.length,
-                                            end_fill_type='NGON',
-                                            view_align=False,
-                                            enter_editmode=False,
-                                            location=location,
-                                            rotation=(0, 0, 0))
+        stick = bpy.ops.mesh.primitive_cylinder_add(vertices=Stick_sectors,
+                                                    radius=Stick_diameter,
+                                                    depth=v.length,
+                                                    end_fill_type='NGON',
+                                                    view_align=False,
+                                                    enter_editmode=False,
+                                                    location=location,
+                                                    rotation=(0, 0, 0))
         # Put the stick into the scene ...
         stick = bpy.context.view_layer.objects.active
         # ... and rotate the stick.
@@ -1107,19 +1164,76 @@ def draw_sticks_normal(all_atoms,
                                    center='MEDIAN')
         sticks = bpy.context.view_layer.objects.active
         sticks.active_material = stick_material
+
+        sticks.location += center
+
+        # Collections
+        # ===========
+        # Note the collection where the sticks were placed into.
+        coll_all = sticks.users_collection
+        if len(coll_all) > 0:
+            coll_past = coll_all[0]
+        else:
+            col

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list