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$
  • 1
    $\begingroup$ have you experimented with hiding / unhiding instead of deleting? that can be keyframed too. $\endgroup$ – zeffii Jul 17 '15 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$ – Henry Ehlers Jul 17 '15 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 Jul 17 '15 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$ – Henry Ehlers Jul 17 '15 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 Jul 17 '15 at 8:42
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$
  • $\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$ – Henry Ehlers Jul 17 '15 at 8:57
  • 1
    $\begingroup$ With big quantities of atoms i'd avoid key framing individual atoms, and suggest an alternative. $\endgroup$ – zeffii Jul 17 '15 at 9:06
  • $\begingroup$ I will try your suggestion of "bpy.app.handlers.frame_change_pre" and "dupli" feature $\endgroup$ – Henry Ehlers Jul 17 '15 at 9:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.