Blender 2.5: Extending grab mode?

Is there a way to write an operator which would go into grab mode (assuming that’s what it’s still called), and then do something in addition to moving the object around?

Let’s say I want to go into grab mode and additionally: change scale based on position, or initially set the mouse cursor to object position, so that, when object is visible on screen, its center is right behind the mouse cursor.


/ten chars

Yes… and 10

Something as this?

##bruno franci - orinoco56
##Testing an operator to grab and to scale at the same time
##Call operator "grabscale" with barspace
##Select one or more objects
##Click and drag with left mouse how many times you want (click only in the view)
##Click right mouse to release operator

import bpy
from bpy.props import * 

class VIEW3D_OT_grabScale(bpy.types.Operator):
    bl_idname = "view3d.grabscale"
    bl_label = "grabscale"
    offset = FloatProperty(name="Offset") 
    lastX = FloatProperty(name="LastX") 
    access = BoolProperty(name="Acess") 
    #To change factor of scale
    scaleX = FloatProperty(name="ScaleX",default=0.1,description="Scale = mouse deplacement * scale - on axis X")
    scaleY = FloatProperty(name="ScaleY",default=0.1,description="Scale = mouse deplacement * scale - on axis Y")
    scaleZ = FloatProperty(name="ScaleZ",default=0.1,description="Scale = mouse deplacement * scale - on axis Z")
    def execute(self, context):
        props =
        objs_sel = [ob for ob in context.scene.objects if ob.selected]
        if len(objs_sel) >=1:
            for ob in objs_sel:
                ob.location[0] += props.offset
                ob.location[1] += 0.0
                ob.location[2] += 0.0
                ob.scale[0] += props.scaleX*props.offset
                ob.scale[1] += props.scaleY*props.offset
                ob.scale[2] += props.scaleZ*props.offset
        return {'FINISHED'}
    def modal(self, context, event):
        objs_sel =  [ob for ob in context.selected_objects]
        if event.type == 'LEFTMOUSE': 
   = True
            if event.value == 'RELEASE':
       = False
       = 0.0
        elif event.type == 'MOUSEMOVE' and == True:
            if == 0.0:
                x = 0
                x =event.mouse_x * 0.05
   = (x - 
   = event.mouse_x * 0.05
        elif event.type in ('RIGHTMOUSE', 'ESC'):
            return {'CANCELLED'}

        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        if context.space_data.type == 'VIEW_3D':
   = 0
   = False
  {'WARNING'}, "Active space must be a View3d")
            return {'CANCELLED'}



Thanks for the script; that will certainly help me.

However, that’s not really extending the operator - you just created a new one, and you had to write the code to change location yourself.

I was hoping that there was a way to extend an existing operator, or to call an existing operator from a custom operator, so that you don’t have to rewrite “grab” in “grabscale”.

@Uncle Entity

How could it be done?

I may be mistaken, but I doubt that python can extend an internal operator
But you can write an operator that call another operator. In your case at the place of ob.location
you can use:
Operator grab
bpy.ops.transform.translate(value=(x,y,z,w) …)
and for ob.scale operator resize
bpy.ops.transform.resize(value=(x,y,z,w) …)

doc here

Yeah, I think you’ll have to write the code yourself.

No way to tell blender to run one operator before another without using python AFAICT.

Once they get macros working though…

event.mouse_x returns the pixel location…how do I get that to a real location in the scene?