Here is a scenario in my addon. There are faces (triangles, quads, polygons) drawn by bgl. They may not have the corresponding Blender mesh counterparts. I'd like to click on on a bgl face and to know which bgl face was hit.

So how would you realize picking bgl faces?


Ray Casting

Currently Blender doesn't have an off-the-shelf solution for this.

Currently ray casting can be realized with the functions from mathutils.geometry:

See also the template Operator Modal View3D Raycastas an example how to deal with viewport coordinates.

However there is a patch to support defining your own BVHTree you can do ray-casts against.


As an alternative you could use a KDTree written in Python (quite a few exist).

Blender mesh as a proxy

As a workaround you could define a mesh who's only purpose is to perform ray-casts on. You can draw it wire-only:

obj_proxy.draw_type = "WIRE"

Here the obj_proxy variable refers to Blender object which mesh is used as the proxy.

OpenGL picking

You could support OpenGL selection by reading back the pixels of the buffer to see which face is under the cursor. See GL_SELECT or ARB_occlusion_query.

(Am not sure enough of OpenGL is exposed by bgl to perform occlusion queries, it may have to be extended - though this would require a custom build or submitting a patch for a future release).

| improve this answer | |
  • $\begingroup$ Custom Blender build isn't an option for me. I am considering a proxy Blender mesh as a solution. Is it possible to change the color and opacity of a specific Blender mesh in the solid mode via python without setting a material? $\endgroup$ – vvoovv Jun 3 '15 at 12:44
  • $\begingroup$ Only one of the options I suggested requires additions to Blender's source. As for using a proxy mesh. You could do this - just set it to draw wire-only. You could also use material with alpha 0.0. and enable object transparency option. $\endgroup$ – ideasman42 Jun 3 '15 at 13:41
  • $\begingroup$ @ideasman42, just to clarify your comment. I think you suggested 3 options: 1) ray casting (requires a custom build for now) 2) Blender mesh proxy (doesn't require a custom build) 3) OpenGL (probably requires a custom build) $\endgroup$ – vvoovv Jun 3 '15 at 14:04
  • $\begingroup$ Ray casting doesn't require a custom build - Python is capable of doing this on its own. You just have to use an existing Python module, or write the code yourself. Eg: code.activestate.com/recipes/… (Though suggest using a BVH-Tree) $\endgroup$ – ideasman42 Jun 3 '15 at 14:06
  • $\begingroup$ @ideasman42, This "OpenGL picking" solution is really interesting. Is it possible to extend the selection buffer to enclose all objects already drawn in Blender? As the cube or the monkey etc. $\endgroup$ – Mano-Wii Jun 3 '15 at 20:35

You can use the functions from mathutils.geometry to deal with geometry

further you can use the functions from view3d_utils to deal with viewport coordinates

From the template operator_modal_view3d_raycast.py:

def main(context, event, ray_max=1000.0):
    """Run this function on left mouse, execute the ray cast"""
    # 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)

    ray_target = ray_origin + (view_vector * ray_max)
| improve this answer | |
  • $\begingroup$ That means looping through all bgl triangles each time. How could the code be optimized if there are too many bgl triangles? $\endgroup$ – vvoovv Jun 2 '15 at 19:00
  • $\begingroup$ for static geometry you can use mathutils.kdtree $\endgroup$ – pink vertex Jun 2 '15 at 20:09
  • $\begingroup$ Not sure if mathutils.kdtree is the right tool here. Image a point P inside a bgl triangle. The point P is located so that the nearest bgl vertex to the point P belongs to another bgl triangle. I can't figure out how mathutils.kdtree could help here. $\endgroup$ – vvoovv Jun 2 '15 at 22:31

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.