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$
  • $\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$ – Duarte Farrajota Ramos Oct 20 '17 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 '17 at 19:44
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$

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.