Code snippet for draw text in 3D

Here you can found an example for draw text in 3D view. Some part are copied from index visualizer. In default scene run the script (space + type modal, then select Simple Modal View3D Move the mouse and you can see the text move

Ciao
ValterVB


import bpy
import bgl
import blf
from mathutils import Vector
def draw_callback_px(self, context):
    # get screen information
    mid_x = context.region.width/2.0
    mid_y = context.region.height/2.0
    width = context.region.width
    height = context.region.height
    # get matrices
    view_mat = context.space_data.region_3d.perspective_matrix
    ob_mat = context.active_object.matrix_world
    total_mat = view_mat*ob_mat
    global tempx
 
    loc=Vector((tempx,0,0)).to_4d() #Where i write the text coordinate relative to the object (x, y, z)
 
    vec=total_mat * loc  # order is important
    vec = Vector((vec[0]/vec[3],vec[1]/vec[3],vec[2]/vec[3]))
    x = int(mid_x + vec[0]*width/2.0)
    y = int(mid_y + vec[1]*height/2.0)
    z=0
 
    # draw some text
    blf.position(0, x, y, z) # 0 is the default font
    blf.size(0, 13, 72) # 0 is the default font
    blf.draw(0, "TEXT TO DRAW") # 0 is the default font
 
class ModalDrawOperator(bpy.types.Operator):
    bl_idname = "view3d.modal_operator"
    bl_label = "Simple Modal View3D Operator"
    def modal(self, context, event):
        context.area.tag_redraw()
        global tempx
        if event.type == 'MOUSEMOVE':
            self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
            tempx = tempx+0.01
        elif event.type == 'LEFTMOUSE':
            context.region.callback_remove(self._handle)
            return {'FINISHED'}
        elif event.type in ('RIGHTMOUSE', 'ESC'):
            context.region.callback_remove(self._handle)
            return {'CANCELLED'}
        return {'RUNNING_MODAL'}
    def invoke(self, context, event):
        if context.area.type == 'VIEW_3D':
            global tempx
            context.window_manager.modal_handler_add(self)
            tempx = 0
            # Add the region OpenGL drawing callback
            # draw in view space with 'POST_VIEW' and 'PRE_VIEW'
            self._handle = context.region.callback_add(draw_callback_px, (self, context), 'POST_PIXEL')
            self.mouse_path = []
            return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, "View3D not found, cannot run operator")
            return {'CANCELLED'}
 
def register():
    bpy.utils.register_class(ModalDrawOperator)
 
def unregister():
    bpy.utils.unregister_class(ModalDrawOperator)
if __name__ == "__main__":
    register()