0
$\begingroup$

To snap the 3D cursor to the surface of my object, I set the "Cursor Depth" to True in the interface user preferences. How can I know exactly to which face/vertice the cursor was snapped (in code)? Do I need to use object.closest_point_on_mesh?

object.closest_point_on_mesh(bpy.context.scene.cursor_location)

Or maybe this data is stored somewhere? Isn't is the whole purpose of Cursor Depth? Also, how can I know which object was it snapped to, in the case of multiple objects in the scene? Thanks!

$\endgroup$
2
  • $\begingroup$ As far as I know Cursor Depth uses the opengl depth buffer for approximate distance. It is not aware of any object geometry or mesh topology, since it may not even be a mesh object it was "snapped to". $\endgroup$ Oct 20, 2017 at 17:09
  • $\begingroup$ I'd go for scene ray cast , as shown in my answer, you could (with depth picking on) loop thru and compare globalized object.closest_point_on_mesh to cursor loc for scene mesh objects. $\endgroup$
    – batFINGER
    Oct 20, 2017 at 19:44

1 Answer 1

1
$\begingroup$

Using Scene.ray_cast


Can shoot a ray into the scene using Scene.ray_cast from the cursor location, in the direction of the converted view matrix's z axis. Test code, prints the ray hit (if hit) of each 3d view in the context screen.

import bpy
from mathutils import Vector
context = bpy.context
screen = context.screen
scene = context.scene
areas3d = [a for a in screen.areas if a.type == 'VIEW_3D']
for a in areas3d:
    r3d = a.spaces.active.region_3d
    vm = r3d.view_matrix.transposed().to_3x3().to_4x4()
    norm = vm * Vector((0, 0, 1))
    norm.normalize() 
    ray = scene.ray_cast(scene.cursor_location, norm)
    hit, loc, norm, face, obj, matrix = ray
    if hit:
        print("hit object", obj, "on face:", face)
$\endgroup$

You must log in to answer this question.

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