0
$\begingroup$

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?

$\endgroup$
4
  • $\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

0
$\begingroup$

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

$\endgroup$

You must log in to answer this question.

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