0
$\begingroup$

I am new to blender and i need to visualise linear transformations. I am using this piece of code to create a timer.

def mod (mid, label, timeout, callback, *args):

    class ModalTimerOperator(bpy.types.Operator):
        bl_idname = mid
        bl_label = label

        _timer = None
        valid = True

        def modal(self, context, event):
            if not self.valid or event.type in {'RIGHTMOUSE', 'ESC'}:
                self.cancel(context)
                return {'CANCELLED'}

            if event.type == 'TIMER':
                self.valid = callback(*args)

            return {'PASS_THROUGH'}

        def execute(self, context):
            wm = context.window_manager
            self._timer = wm.event_timer_add(timeout, context.window)
            wm.modal_handler_add(self)
            return {'RUNNING_MODAL'}

        def cancel(self, context):
            wm = context.window_manager
            wm.event_timer_remove(self._timer)

    bpy.utils.register_class(ModalTimerOperator)

so i am assuming function callback (args...) gets called every time after timeout seconds.

So overall i am creating a cube then creating two timers with different timeouts. one does a translation and other does Rotation. But the problem with the timers is that, instead of firing every timeout seconds it is firing continuously one after another without the timeout delay. Happens when multiple timers are present

mymesh =  makeCube () 

translateMatrix = mathutils.Matrix.Translation( mathutils.Vector((0, 0, 1)) )
rotationMatrix  = mathutils.Matrix.Rotation(math.radians(45.0), 3, "Z")

mod("wm.a", "a", 2,   transformation, mymesh, translateMatrix, True)
mod("wm.b", "b", 0.1, transformation, mymesh, rotationMatrix,  True)

bpy.ops.wm.a();
bpy.ops.wm.b();

Please Help me. Here is overall code.

import mathutils
import math 
import bpy
import bmesh

def clean():
    for i in bpy.data.objects:
        i.select = True
        bpy.ops.object.delete()

def mod (mid, label, timeout, callback, *args):

    class ModalTimerOperator(bpy.types.Operator):
        bl_idname = mid
        bl_label = label

        _timer = None
        valid = True

        def modal(self, context, event):
            if not self.valid or event.type in {'RIGHTMOUSE', 'ESC'}:
                self.cancel(context)
                return {'CANCELLED'}

            if event.type == 'TIMER':
                self.valid = callback(*args)

            return {'PASS_THROUGH'}

        def execute(self, context):
            wm = context.window_manager
            self._timer = wm.event_timer_add(timeout, context.window)
            wm.modal_handler_add(self)
            return {'RUNNING_MODAL'}

        def cancel(self, context):
            wm = context.window_manager
            wm.event_timer_remove(self._timer)

    bpy.utils.register_class(ModalTimerOperator)

def makeCube ():
    verts = [ (0, 0, 0), (0, 5, 0), (5, 5, 0), (5, 0, 0), (0, 0, 5), (0, 5, 5), (5, 5, 5), (5, 0, 5) ]
    faces = [ (0, 1, 2, 3), (7, 6, 5, 4), (0, 4, 5, 1), (1, 5, 6, 2), (2, 6, 7, 3), (3, 7, 4, 0) ]
    edges = []

    mymesh = bpy.data.meshes.new("supershape")
    myobject = bpy.data.objects.new("supershape",mymesh)

    myobject.location.x = 0
    myobject.location.y = 0
    myobject.location.z = 0

    bpy.context.scene.objects.link(myobject)

    mymesh.from_pydata(verts,edges,faces)
    mymesh.update(calc_edges=True)

    myobject.select = True
    bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_VOLUME')

    return mymesh

def transformation (mesh, matrix, ret):

    bm = bmesh.new()
    bm.from_mesh(mesh)

    #Modify the vertices of mesh
    for v in bm.verts:
        v.co = matrix * v.co

    # update mesh 
    bm.to_mesh(mesh)
    mesh.update (calc_edges = True)
    bm.free()
    return ret 

clean()                #remove all the objects
mymesh =  makeCube () 

translateMatrix = mathutils.Matrix.Translation( mathutils.Vector((0, 0, 1)) )
rotationMatrix  = mathutils.Matrix.Rotation(math.radians(45.0), 3, "Z")

mod("wm.a", "a", 2,   transformation, mymesh, translateMatrix, True)
mod("wm.b", "b", 0.1, transformation, mymesh, rotationMatrix,  True)

bpy.ops.wm.a();
bpy.ops.wm.b();
$\endgroup$
  • $\begingroup$ Confused as to what the question is here. Yes the timers run continously firing a 'TIMER' event every timeout seconds. Suggest looking into a frame change handler to do this. see Handlers , or some other method like drivers, that utilize the animation system built into blender. $\endgroup$ – batFINGER Aug 14 '18 at 12:57
  • $\begingroup$ @batFINGER i am sorry, i wanted to say that instead of firing every timeout seconds it is firing continuously one after another without the timeout delay. Happens when multiple timers are present $\endgroup$ – Atul Aug 14 '18 at 13:10
  • $\begingroup$ Ok, recall another question about that. Would use one timer and give each callout a count (eg timer every 0.1 seconds, rotate:1 translate:20) or as mentioned prior use a frame change handler. $\endgroup$ – batFINGER Aug 14 '18 at 13:15
  • $\begingroup$ May find this useful too $\endgroup$ – batFINGER Aug 14 '18 at 13:24
  • $\begingroup$ @batFINGER yes. its better to use single timer and figure out which functions to run. Thank you. $\endgroup$ – Atul Aug 14 '18 at 13:49

Your Answer

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

Browse other questions tagged or ask your own question.