I'm trying to draw text in 3d space, but it draws in wrong coordinates and not directed at the screen. As from here Text in 3D view linked to an object. It work correctly with modal, but did not with this class. How it look:
How it needed:
import bpy
import blf
from mathutils import Vector
from bpy_extras.view3d_utils import location_3d_to_region_2d
def view3d_find( return_area = False ):
for area in bpy.context.window.screen.areas:
if area.type == 'VIEW_3D':
v3d = area.spaces[0]
rv3d = v3d.region_3d
for region in area.regions:
if region.type == 'WINDOW':
if return_area: return region, rv3d, v3d, area
return region, rv3d, v3d
return None, None
class DrawingClass:
def __init__(self):
self.handle = bpy.types.SpaceView3D.draw_handler_add(self.draw_text, (), 'WINDOW', 'POST_VIEW')
def draw_text(self):
font_id = 0
obj = bpy.context.active_object
# v3d = bpy.context.space_data
# rv3d = v3d.region_3d
# region = bpy.context.region
region, rv3d, v3d = view3d_find()
pos = location_3d_to_region_2d(region, rv3d, obj.location)
pos_x = pos[0]
pos_y = pos[1]
# draw function
blf.position(font_id, pos_x, pos_y, 0)
blf.size(font_id, 20)
blf.draw(font_id, obj.name)
def remove_handle(self):
bpy.types.SpaceView3D.draw_handler_remove(self.handle, 'WINDOW')
# to draw
dns = bpy.app.driver_namespace
dns["dc"] = DrawingClass()
# to remove
dns = bpy.app.driver_namespace
dc = dns.get("dc")
dc.remove_handle()
pos = obj.location
I think $\endgroup$blf.position(font_id, pos_x, pos_y, 0)
change toblf.position(font_id, *obj.location)
andblf.size(font_id, 20)
change toblf.size(font_id, 20, 72)
. If you want display 2D,'POST_VIEW'
change to'POST_PIXEL'
$\endgroup$