This script (below) allows us to see in real time the point’s coordinates where the mouse hits the activated object. It works well in “Object Mode”.
But in the “Edit Mode” the “Object ‘Cube’ has no mesh data to be used for ray casting”.
WHY? I need to use bmesh? What?
import bpy
from bpy_extras import view3d_utils
from bpy.props import FloatVectorProperty
def main(context, event, ray_max=1000.0):
# get the context arguments
scene = context.scene
region = context.region
rv3d = context.region_data
coord = event.mouse_region_x, event.mouse_region_y
# get the ray from the viewport and mouse
view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
if rv3d.view_perspective == 'ORTHO':
# move ortho origin back
ray_origin = ray_origin - (view_vector * (ray_max / 2.0))
ray_target = ray_origin + (view_vector * ray_max)
def obj_ray_cast(obj, matrix):
"""Wrapper for ray casting that moves the ray into object space"""
# get the ray relative to the object
matrix_inv = matrix.inverted()
ray_origin_obj = matrix_inv * ray_origin
ray_target_obj = matrix_inv * ray_target
# cast the ray
hit, normal, face_index = obj.ray_cast(ray_origin_obj, ray_target_obj)
if face_index != -1:
return hit, normal, face_index
else:
return None, None, None
# no need to loop through other objects since we are interested in the active object only
obj = context.scene.objects.active
matrix = obj.matrix_world.copy()
if obj.type == 'MESH':
hit, normal, face_index = obj_ray_cast(obj, matrix)
if hit is not None:
hit_world = matrix * hit
return hit_world
else:
return view_vector
#return None
class ViewManoOperator(bpy.types.Operator):
"""using mouse events"""
bl_idname = "view3d.mano_operator"
bl_label = "View Mano Operator"
hit = FloatVectorProperty(name="hit", size=3)
def modal(self, context, event):
if event.type == 'MOUSEMOVE':
self.hit = main(context, event)
context.area.header_text_set("hit: %.4f %.4f %.4f" % tuple(self.hit))
return {'RUNNING_MODAL'}
elif event.type in {'LEFTMOUSE', 'RIGHTMOUSE', 'ESC'}:
context.area.header_text_set()
return {'CANCELLED'}
return {'RUNNING_MODAL'}
def invoke(self, context, event):
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
def register():
bpy.utils.register_class(ViewManoOperator)
def unregister():
bpy.utils.unregister_class(ViewManoOperator)
if __name__ == "__main__":
register()