2
$\begingroup$

New to blender. Here's my dilemma. I am dynamically animating a protein network using a python-script using user-provided text-files. The animation is done using key-framing for each object's actions (see below - self.frame_number and self.disjointed_frame allow the class in question to remember what frame the animation is on)

    def add_progressive_location_keyframe(self, frame_step):

        bpy.context.scene.frame_end += frame_step
        bpy.context.object.keyframe_insert(data_path="location", frame=self.frame_number)
        self.frame_number += frame_step
        self.disjointed_frame += frame_step

So far, animating reactions that merely involve the transloation of one protein from one location to another have worked fine. However, some reactions involve two proteins forming a complex, a new protein. In this case, I have to dynamically delete the two reactants in a certain key-frame and in that same frame create the product. However, I cannot add a key-frame to an object I have deleted and I am unable to add a key-frame to an object that doesn't yet exist. This results in the two reactants being deleted and the product being formed in frame 0 (the first one).

My question: How can I add key-frames to these objects in order to dynamically delete and create them in certain frames? Is there a work around I am unfamiliar with? Your help is much appreciated.

$\endgroup$
6
  • 1
    $\begingroup$ have you experimented with hiding / unhiding instead of deleting? that can be keyframed too. $\endgroup$
    – zeffii
    Commented Jul 17, 2015 at 8:29
  • $\begingroup$ I have considered that approach, but that would require me to create all required objects (thousands) at the very beginning of the animation. $\endgroup$ Commented Jul 17, 2015 at 8:31
  • $\begingroup$ You know the position of all these atoms in advance? (ie you aren't using blender game engine to calculate reactions) $\endgroup$
    – zeffii
    Commented Jul 17, 2015 at 8:31
  • $\begingroup$ Correct. The animations are all deterministic/'predefined'. The data being fed to pyhton, and by extension blender, would allow me to place all the necessary objects in the right place and then hide/unhide them as the animation proceeds. However, can blender even handle that kind of object load and ensure a smooth animation? $\endgroup$ Commented Jul 17, 2015 at 8:34
  • $\begingroup$ I'm willing to help you do this, can you provide a small sample file or do you only have the massive file? I work on an addon called BioBlender and this is a feature i was going to add anyway.. $\endgroup$
    – zeffii
    Commented Jul 17, 2015 at 8:42

1 Answer 1

2
$\begingroup$

In that case I propose

  • preprocess the file into separate files per frame ( Alternatively create a cache dict if you have plenty of RAM, that way you avoid having to deal with writing/reading extra files :) )
  • store each cloud of atom types and their coordinates something like

this:

 C x y z
 C x y z
 C x y z
 N x y z
 N x y z 
  • write a file reader that can take each frame's file and

    • on the first frame

      1. check if the object in the next step exists already, skip this step if it does.
      2. create a vertex based mesh object for each type of atom ( ie create a vertex for every atom of one type and put those in an object named something like atom_cloud_C, and do the same for all other atom types ). Meaning, if your file only has 3 C atoms, that your atom_cloud_C only has 3 verts.
      3. on subsequent frames you read the next frame's file and overwrite the coordinates of each atom, for all atom types.

        code:

        f_v = list(itertools.chain.from_iterable(verts))
        mesh.vertices.foreach_set('co', f_v)
        mesh.update()
        
  • This produces clouds of atoms as different objects, which get updated every frame.

  • Then create the spheres that represent each atom type (only need one sphere per atom type)
  • Then use the dupli feature set to Verts to duplicate the various spheres that represent the atom. (this is a low memory way to display many spheres )
  • instead of keyframing it all, you can attach a bpy.app.handlers.frame_change_pre to perform a function on each frame change (pre or post), examples for this can be found in the documentation.
$\endgroup$
3
  • $\begingroup$ Great! This is pretty similar to what I have so altering my code shouldn't be too bad. Thanks a lot for the help! $\endgroup$ Commented Jul 17, 2015 at 8:57
  • 1
    $\begingroup$ With big quantities of atoms i'd avoid key framing individual atoms, and suggest an alternative. $\endgroup$
    – zeffii
    Commented Jul 17, 2015 at 9:06
  • $\begingroup$ I will try your suggestion of "bpy.app.handlers.frame_change_pre" and "dupli" feature $\endgroup$ Commented Jul 17, 2015 at 9:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .