Is there a way to determine if the cursor /object is currently snap on object? In this case on the face:
Closest Point on Mesh
Takes a point in object space and returns the hit result, the location of hit, the normal of face hit and the face's index.
Alternatively could utilize
mathutils.geometry.distance_point_to_plane(...), where each plane is defined by face center and face normal. Edit, this is somewhat flawed since the cursor can be on a faces plane but outside its edges, which would need to be tested for
Both these methods require the point to be in object space. The 3d cursor location is in global space, convert using
pt = o.matrix_world.inverted() @ scene.cursor.location
Here is a verbose script using both methods. The
on_face boolean is true if cursor is on face of an object.
Note testing shows the tolerance
TOL (distance from point to face) needs to be in the vicinity of
import bpy from mathutils.geometry import distance_point_to_plane as dp2p context = bpy.context scene = context.scene dg = context.evaluated_depsgraph_get() TOL = 5e-5 # Tolerance mesh_obs = [o for o in context.scene.objects if o.type == 'MESH'] for o in mesh_obs: me = o.data print(o.name, me.name) #cursor location in o's object space pt = o.matrix_world.inverted() @ scene.cursor.location # using closest point on mesh hit, loc, n, i = o.closest_point_on_mesh(pt, depsgraph=dg) print(i, (pt - loc).length) on_face = hit and (pt - loc).length < TOL print("closest point on mesh", on_face) # using distance point to plane for each face for p in me.polygons: print(p.index, dp2p(pt, p.center, p.normal)) on_face = any(abs(dp2p(pt, p.center, p.normal)) < TOL for p in me.polygons) print("plane distance", on_face)
Result of running on default cube after clicking to snap cursor to face from view.
Cube Cube 3 2.1159816795005355e-05 closest point on mesh True 0 -0.9940524101257324 1 -1.0059475898742676 2 -1.1975289583206177 3 2.104043960571289e-05 4 -0.8024709224700928 5 -2.000020980834961 plane distance True