I have a point in 3d view (found out with region_2d_to_origin_3d of mouse position). I want to find its projection on a plane defined by a normal (x1, y1, z1) in orthographic view. How to do this? enter image description here

Edit: Attaching a sample blend file with the script I am trying to run. If you run the modal operator from the perspective view and move the mouse pointer, the Bezier line always lies on the plane (which is the desired functionality). But the same operator from orthographic view does not produce any movement.

  • $\begingroup$ Elements to do that here blender.stackexchange.com/questions/150267/… $\endgroup$
    – lemon
    Commented Sep 3, 2019 at 12:21
  • $\begingroup$ @lemon Thank you! I don't have a plane object, just the points on plane, so I am using geometry.intersect_ray_tri and giving it three points on the plane. The problem is finding the start and end of the ray. Using view_matrix gives correct results in perspective view but not in orthographic view. So I thought of exploring the mathematical route. $\endgroup$
    – greentail
    Commented Sep 3, 2019 at 12:30
  • $\begingroup$ region_2d_to_origin_3d is the origin of the view. region_2d_to_location_3d gives the mouse 3D pos from mouse pos. So you have things in order to ray cast. Both are available in ortho. But maybe I've not understood the issue? $\endgroup$
    – lemon
    Commented Sep 3, 2019 at 12:39
  • $\begingroup$ @lemon Yes, I am just looking for what you have given in the example. And the script given by you works for both perspective & orthographic views. The only change needed is I don't have the 'Plane' object (and creating a temp object is not desirable). I just have 3 non-linear points defining the plane and I want to orient the cube along the normal of this plane in orthographic view. $\endgroup$
    – greentail
    Commented Sep 3, 2019 at 13:14
  • $\begingroup$ Well, intersect_ray_tri should work. Or you need something around that? $\endgroup$
    – lemon
    Commented Sep 3, 2019 at 13:22

1 Answer 1


The code can be the following.

We principally need the view vector (axis from the camera) and the view point (cam/eye position) which are given by view3d_utils.region_2d_to_vector_3d and view3d_utils.region_2d_to_origin_3d.

Then we cast on the plane coordinates in two parts as the plane is two tris.

    # Get mouse position
    mouse_pos = event.mouse_region_x, event.mouse_region_y

    # Get object and region 3D
    object = context.object
    region = context.region
    region3D = context.space_data.region_3d

    # The target plane in order to have coordinates
    plane = bpy.data.objects.get('Plane')

    # All Transforms applied, so global space coordinates
    # (Plane is used just to get the points, in actual situation only 
    # points will be available)
    p1 = plane.data.vertices[0].co
    p2 = plane.data.vertices[1].co            
    p3 = plane.data.vertices[2].co            
    p4 = plane.data.vertices[3].co            

    # View vector (view axis) from the mouse pos
    view_vector = view3d_utils.region_2d_to_vector_3d(region, region3D, mouse_pos)
    # View point (eye position) in 3D
    view_point = view3d_utils.region_2d_to_origin_3d(region, region3D, mouse_pos)

    # Cast on plane defined by points above (2 counterclockwise tris)
    loc = geometry.intersect_ray_tri(p1, p2, p3, view_vector, view_point, True)
    if not loc:
        loc = geometry.intersect_ray_tri(p2, p4, p3, view_vector, view_point, True)

Note: have left the plane coordinates part as it was, but can also use the plane world matrix to translate coordinates to world.


You must log in to answer this question.

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