Access subframe particles

Hi!

I have this script working fine when I try to move the timeline with full frame. But when I try to move the timeline with subframe … particles just go crazy.

Here is code

import bpy
import time
global csubframe
vSubFrame = 3
bpy.context.object.particle_systems[0].settings.subframes = vSubFrame
 
csubframe = 0
cframe =1
def Refresh():
    bpy.data.scenes[0].update()
class ModalTimerOperator(bpy.types.Operator):
    '''Operator which runs its self from a timer.'''
    bl_idname = "wm.modal_timer_operator"
    bl_label = "Modal Timer Operator"
    _timer = None
    def modal(self, context, event):
        global csubframe
        global cframe
        if event.type == 'ESC':
            return self.cancel(context)
        if event.type == 'TIMER':
            # change theme color, silly!
            print("Start frame: "+str(bpy.context.scene.frame_current+bpy.context.scene.frame_subframe))
            stime = time.clock()
            etime = time.clock()
            print ("    >Frame: " + str(bpy.context.scene.frame_current+bpy.context.scene.frame_subframe) + "  in  " + (str("%-6.4f"%(etime - stime)))+'sec ...............')                 
            csubframe = 1/(vSubFrame+1)+csubframe
            if csubframe >= 1:
                csubframe = 0
                cframe = (cframe + 1)
            bpy.data.scenes[0].frame_set(frame=cframe,subframe=csubframe)
            Refresh()
        return {'PASS_THROUGH'}
    def execute(self, context):
        context.window_manager.modal_handler_add(self)
        self._timer = context.window_manager.event_timer_add(0.1, context.window)
        return {'RUNNING_MODAL'}
    def cancel(self, context):
        context.window_manager.event_timer_remove(self._timer)
        return {'CANCELLED'}
 
def register():
    bpy.utils.register_class(ModalTimerOperator)
 
def unregister():
    bpy.utils.unregister_class(ModalTimerOperator)
 
if __name__ == "__main__":
    register()
    # test call
    bpy.ops.wm.modal_timer_operator()

Step1: Create a empty scene with the default cube
Step2: Copy & Paste my script in a new text
Step3: Create a Particles System on the cube
Step4: Make start and end frame to 1 ( to get every particle at frame 1 but it’s can work without this step too)
Step5: Keep the cube selected and RUN the script

ESC to stop the script

Somebody have a idea ? A error in my script or I do it in a wrong way ?

Thanks !

Somebody try it and know why?

Ok … I write some ouput to try finding what going one with the subframe bugs.
After the last subframe of the frame1 , the prev_location stay the same for ever !
And the velocity reset to the last velociy of the frame1 for every next full frame !

just take a look on this console output:

http://www.pasteall.org/25674/text

New script too get this:

import bpy
import time
global csubframe
print("SCRIPT START HERE ------------")
vSubFrame = 3
bpy.context.object.particle_systems[0].settings.subframes = vSubFrame
csubframe = 0
cframe =1
bpy.data.scenes[0].frame_set(frame=1,subframe=0)
def Refresh():
    bpy.data.scenes[0].update()
class ModalTimerOperator(bpy.types.Operator):
    '''Operator which runs its self from a timer.'''
    bl_idname = "wm.modal_timer_operator"
    bl_label = "Modal Timer Operator"
    _timer = None
    def modal(self, context, event):
        global csubframe
        global cframe
        global prevloc
        if event.type == 'ESC':
            return self.cancel(context)
        if event.type == 'TIMER':           
            print("Start frame: "+str(bpy.context.scene.frame_current+bpy.context.scene.frame_subframe))
            stime = time.clock()
            etime = time.clock()                
            print("    >Velocity: "+str(bpy.context.object.particle_systems[0].particles[0].velocity))
            print("    >Location: "+str(bpy.context.object.particle_systems[0].particles[0].location))
            print("    >Prev Location: "+str(bpy.context.object.particle_systems[0].particles[0].prev_location))
            print("    >Prev Velocity: "+str(bpy.context.object.particle_systems[0].particles[0].prev_velocity))
            print ("   >Frame: " + str(bpy.context.scene.frame_current+bpy.context.scene.frame_subframe) + "  in  " + (str("%-6.4f"%(etime - stime)))+'sec ...............') 
            csubframe = 1/(vSubFrame+1)+csubframe
            if csubframe >= 1:
                csubframe = 0
                cframe = (cframe + 1)
            bpy.data.scenes[0].frame_set(frame=cframe,subframe=csubframe)
            Refresh()
        return {'PASS_THROUGH'}
    def execute(self, context):
        context.window_manager.modal_handler_add(self)
        self._timer = context.window_manager.event_timer_add(0.1, context.window)
        return {'RUNNING_MODAL'}
    def cancel(self, context):
        context.window_manager.event_timer_remove(self._timer)
        return {'CANCELLED'}
 
def register():
    bpy.utils.register_class(ModalTimerOperator)
 
def unregister():
    bpy.utils.unregister_class(ModalTimerOperator)
 
if __name__ == "__main__":
    register()
    # test call
    bpy.ops.wm.modal_timer_operator()