I've been on this for too long...

I can get an object to follow the screen position of the mouse after a mouse click (event.value == 'PRESS'), but I'd like to constrain it to the objects LOCAL Z axis while the user holds said mouse button.

I can use:

loc, rot, sca = obj.matrix_world.decompose()
bpy.ops.transform.translate('INVOKE_DEFAULT', orient_matrix=rot.to_matrix().to_3x3(), orient_matrix_type='LOCAL', constraint_axis=(False, False, True))

to invoke a move that is constrained, but I'd like to be able to run other code while the user holds the mouse button, using bpy.ops does not allow this. (not that I know of...)

Anyone know how I can grab an object and move it while staying constrained to one of the objects LOCAL axis only while the user holds a mouse button without bpy.ops.transform.translate?

  • $\begingroup$ Probably you should write your own operator. $\endgroup$
    – Crantisz
    Aug 12, 2022 at 13:02
  • $\begingroup$ Hey @Crantisz Yeah, that's what I have, a modal operator that takes all the visible objects in a View Layer, gets their evaluated version, joins them into a single object and slices them at a face the user selects. I want to be able to then grab an object I create and move it constrained to it's LOCAL Z axis and adjust the slice position (Like a Section View operator in most CAD programs) It works great, but I can't figure out the last part... Grab the object interactively and adjust the slice position while the user holds a mouse button. $\endgroup$
    – Psyonic
    Aug 12, 2022 at 13:10
  • $\begingroup$ So that is the problem? Run modal operator and change object position in modal event without using OPS functions $\endgroup$
    – Crantisz
    Aug 12, 2022 at 13:14
  • $\begingroup$ While constraining it to it's LOCAL Z axis, and only while user holds a mouse button, yes $\endgroup$
    – Psyonic
    Aug 12, 2022 at 13:15

1 Answer 1


For anyone else wondering the same thing, this is how I solved this.

To be honest, the hold mouse button part was a little embarrassing I didn't figure it out sooner ☺️

You simply need to remember the if event.value == 'PRESS': and forget it on elif event.value == 'RELEASE':

For example:

if event.type == 'LEFTMOUSE':
  if event.value == 'PRESS':
      left_mouse_pressed = True

  elif event.value == 'RELEASE':
      left_mouse_pressed = False

Then in if event.type == 'MOUSEMOVE': use that flag to do your work:

if event.type == 'MOUSEMOVE':
    if left_mouse_pressed == True:
        # do stuff here

For getting an object to move on it's LOCAL axis, this was a little trickier, but I learned some things along the way so thought I'd share.

There are several ways to get a vector of your objects local axis, I used this found here: Is there a simpler way to get the Vectors of a local axis? from @Robert Gützkow

obj = bpy.data.objects["Cube"] # Replace with your own object selection    
translation, rotation, scale = obj.matrix_world.decompose()
local_z_axis = Vector((0.0, 0.0, 1.0)) # this is X,Y,Z change to 1.0 for the axis you want
local_z_axis_global_coords = rotation @ local_z_axis 

Then, to have the object move along it's Z axis with the mouse movement that is parallel with that axis, this is what I used:

region = context.region
rv3d = context.region_data
mouse_pos = event.mouse_region_x, event.mouse_region_y
view_loc = view3d_utils.region_2d_to_location_3d(region, rv3d, mouse_pos, obj.location)
obj_z_axis_1 = obj.location
obj_z_axis_2 = obj.location + local_z_axis_global_coords
mouse_to_obj_z_axis = mathutils.geometry.intersect_point_line(view_loc, obj_z_axis_1, obj_z_axis_2)
obj.location = mouse_to_obj_z_axis[0]

view3d_utils.region_2d_to_location_3d finds a location in 3D space under your mouse and at the same depth as your object, then mathutils.geometry.intersect_point_line gets the closest point to that mouse position along an imaginary line based on your objects axis, in my case the Z axis, and obj.location = mouse_to_obj_z_axis[0] moves the object to that point.

Hope this helps someone as it took me quite some time to find all the pieces


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .