Raycasting in a UV view?

What’s the best way to do this? From what I can tell all of the raycast methods in the Python API revolve around raycasting to a 3D view. Is there some way to raycast in a image editor area and determine what element is under the mouse cursor? The best thing I’ve come up with is dumping all of the UV coordinates into a KDTree (after first converting them to vec3 and transforming them based on the view2D screen offset). This sounds… awful. I’d really rather not do some hacky crap if I can avoid it, surely there is a way to raycast to a 2D View??

edit: not even the kdtree trick will work since there doesn’t appear to be any way to get the mouse position in the normalized location expected for pretty much every IMAGE_EDITOR operator!? On top of that the us.select operator doesn’t work when used from another operator (even with an overridden context).

The more work I do in the UV editor the more I wonder why Blender even has one, it’s so neglected that it’s embarassing and my best efforts to make it more usable for my studio are being met with neutered python api access. Any ideas here would be extremely appreciated!

meh… went with a hackfest solution. caching current loop selection into a list, then using uv.select with invoke_default- grabbing the closest element, for my operator, then restoring the selection.

Not sure what you mean by “normalized location” exactly, but I guess what you need is this: https://docs.blender.org/api/blender2.8/bpy.types.View2D.html#bpy.types.View2D

Every 2D region in Blender has an instance of this. It can be used to convert between region-space (mouse coordinates starting from the bottom left of the region) and the coordinates used by the uvs.

You can then just iterate over all uvs to find the closest or use a kdtree when you need to do this operation many times without the uvs changing inbetween.

2 Likes

You are correct- region_to_view is the answer. I had found it before but was using it incorrectly and getting unexpected results so I dismissed it. Passing in the event mouse coordinates to region_to_view correctly gives the mouse position in UV space.