# Python - Baking vertices position for a frame range

I wrote script that create a custom deformer to a mesh over time. Using python is very slow so I'd like to be able to bake the position of my vertices deformed over time and be able to play it back at a better frame rate.

So, I'm trying to find a good solution to bake the position of vertices of a mesh over time like the physics/rigid body system in Blender.

I guess there is no direct access to create my own internal point cache (but if somebody knows how to do that I'm interested) so what I plan to do is to have a list that store the position of my vertices for a range of frames. As I'd like to be able to cancel while baking (using 'ESC'), I guess using a modal operator is the best way to go but i can't get my head around how to set up the modal operator particularly with the return values.

Here is what I get so far:

import bpy

##some code##

##store global
class G:
pass

## bake deformer
class JDEF_BAKE(bpy.types.Operator):
bl_idname = "wm.bake_jdef"
bl_label = "Bake deformer"
bl_options = {'UNDO', 'REGISTER'}

_frame = 1
_bake_mat = []
_index = 0
obj = None
_endframe = 0

def __init__(self):
self.obj = bpy.context.object
G.baked=False
G.baking=True
self._frame = bpy.context.scene.frame_start
G.ls_bake=[]
self._bake_mat = [0.0,0.0,0.0]*len(self.obj.data.vertices)
self._endframe = bpy.context.scene.frame_end

def __del__(self):
G.baked=True
G.baking=False

def execute(self,context):
context.scene.frame_current = self._frame
JDEF(context) #execute some function to move the vertices
self.obj.data.vertices.foreach_get('co',self._bake_mat)
G.ls_bake.append([self._frame,self._bake_mat])
self._frame += 1
return {'RUNNING_MODAL'}

## bake deformer
def modal(self,context,event):
if (self._frame <= self._endframe):
self.execute(context)

elif (self._frame > self._endframe):
return {'FINISHED'}

elif event.type=='ESC':
G.baked=True
G.baking=False
G.ls_bake.clear()
return {'CANCELLED'}

return {'PASS_THROUGH'}


So this doesn't seems to work and blender freezes each time I launch the operator. It doesn't come from the function JDEF because even if I comment it blender will still froze. I think I'm not handling the return values and execute/modal functions the right way.

Sorry if the bad code make you tear blood but I'm still a learning noob :D

• First try to rename your __init__(self) to invoke(self,context,event). Invoke is what is called when the modal is invoked. Inside that fce move the context.window_manager.modal_handler_add(self) - you want to run that only once. Erase the execute and move it under modal. Execute don't return Running modal and you are using it only there under modal. If this works for you I will post it as an answer, cant test your code. Dec 29 '14 at 19:11
• Thx! I'll try that and let you know. I wonder what would be the use for the __init__(self) def then in comparison of the invoke()? Dec 29 '14 at 19:47
Ok, unfortunately @Jerryno solution didn't work so I ended up trying something else. I successfully made it wok by triggering the animation with bpy.ops.screen.animation_play() in the __init__ function, then doing my action in the modal function and finally stop the animation when 'ESC' is entered or the action is finished (in the __del__ function).
The handler is added in an invoke function running modal.