0
$\begingroup$

I'm listening to the right click in my model operator. I wish to get its 3D coordinates in the 3D_view. I've tried the following code from here:

from bpy_extras.view3d_utils import region_2d_to_vector_3d, region_2d_to_location_3d
def mouse_coo_to_3d_loc(event, context):
    coord = (event.mouse_region_x, event.mouse_region_y)
    region = context.region
    rv3d = context.space_data.region_3d
    vec = region_2d_to_vector_3d(region, rv3d, coord)
    return region_2d_to_location_3d(region, rv3d, coord, vec)

But I got different coordinates from bpy.context.scene.cursor_location. I thought that maybe the context is wrong, so I used this code instead:

def mouse_coo_to_3d_loc(event):
    area, region = get_3d_area_region()
    coord = (event.mouse_x - area.x, event.mouse_y - area.y)
    rv3d = area.spaces.active.region_3d
    vec = region_2d_to_vector_3d(region, rv3d, coord)
    return region_2d_to_location_3d(region, rv3d, coord, vec)

def get_3d_area_region():
    for screen in bpy.data.screens:
        for area in screen.areas:
            if area.type == 'VIEW_3D':
                for region in area.regions:
                    if region.type == 'WINDOW':
                        return area, region

But still wrong results. Am I m missing something here?

**** EDIT ****

I should have mentioned that my addon is running in the graph_editor.

$\endgroup$
  • $\begingroup$ blender.stackexchange.com/questions/13450/… $\endgroup$ – yhoyo Nov 7 '17 at 21:46
  • $\begingroup$ What is the issue here? the code works as described. Invoke the operator via button or space bar in 3d view. Substituting setting the cursor location instead of moving context object sets the cursor location as expected. What's the point of get_3d_area_region() above? will always return the VIEW_3D area of bpy.data.screens[0] .. (or first with 3d view, eg "3D Full VIew" screen in default file.) $\endgroup$ – batFINGER Nov 8 '17 at 3:26
  • $\begingroup$ Ah, sorry, I should have mentioned that my addon is running in the graph_editor. That might be the reason. $\endgroup$ – Noam Peled Nov 8 '17 at 16:12
1
$\begingroup$

Get screen from context.screen or context.window.screen

Get the clicked area by looking at area coordinates, of each area, in the screen returned from context.screen or context.window.screen. Used the latter in example below, my tests suggest could use either. The region can be obtained from the area.

    if event.type == 'RIGHTMOUSE' and event.value == 'PRESS':
        screen = context.window.screen # or context.screen
        def get_click_area():            
            for a in screen.areas:
                if (a.x < event.mouse_x < a.x + a.width
                and a.y < event.mouse_y < a.y + a.height):
                    return a
        a = get_click_area()
        print("Right Clicked in %s area of screen %s" % (a.type, screen.name))

as mentioned in my comment, get_3d_area_region() above, will only return the first matching area it finds in the bpy.data.screens collection. For the default file will be bpy.data.screens["3D Full View"].areas[1] every time.

$\endgroup$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.