Vista 3D: ¿cómo mostrar los datos de la cámara en el marco de la cámara?
¿Hay alguna manera de utilizar opciones de visualización como "información del objeto" o "nombre de la vista" (en las preferencias de la ventana gráfica) para mostrar otra información como, por ejemplo, la distancia focal de la cámara activa y su posición? ¿Y hay alguna forma de mover esta información a cualquier lugar de la ventana 3D? Como en este ejemplo:

Entonces encontré un script que me permite mostrar el punto focal en la ventana 3D.
import bpy
import blf
dns = bpy.app.driver_namespace
dc = dns.get("dc")
dc.remove_handle()
class DrawingClass:
def __init__(self, context, prop):
self.prop = prop
self.handle = bpy.types.SpaceView3D.draw_handler_add(
self.draw_text_callback,(context,),
'WINDOW', 'POST_PIXEL')
def draw_text_callback(self, context):
font_id = 0 # XXX, need to find out how best to get this.
# draw some text
blf.position(font_id, 15, 350, 0)
blf.size(font_id, 20, 72)
blf.draw(font_id, "%s %s" % (context.scene.name, self.prop))
def remove_handle(self):
bpy.types.SpaceView3D.draw_handler_remove(self.handle, 'WINDOW')
context = bpy.context
dns = bpy.app.driver_namespace
dns["dc"] = DrawingClass(context, bpy.context.object.data.lens)

Las primeras 3 líneas me permiten borrar la pantalla anterior. ¿Cómo puedo evitar que scipte lea las primeras 3 líneas la primera vez que se ejecuta el script? Por ahora, el guión lee el foco una vez y lo escribe. ¿Cómo asegurarse de que se lea el guión cada vez que se cambie el foco?
Respuestas
AFAIK, eso no es posible por defecto y supongo que no existe ningún complemento que pueda mostrar cualquier tipo de información en el marco de la cámara.
Sin embargo, puede dibujar el texto usando el módulo bgl de python y crear su propio complemento. El siguiente código de ejemplo se basa en nuestra famosa plantilla Operator Modal Draw que viene con Blender, ampliada con las respuestas de Coordenadas de las esquinas del borde de la vista de la cámara y Texto de varias líneas en blf (con opción de varios colores) para que la bola ruede:

hud.py
import bpy
import blf
import bgl
# -> BASED ON: https://blender.stackexchange.com/a/14746/31447
def view3d_find(context):
# returns first 3d view, normally we get from context
for area in 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':
return region, rv3d
return None, None
def view3d_camera_border(context):
obj = context.scene.camera
cam = obj.data
frame = cam.view_frame(scene=context.scene)
# move from object-space into world-space
frame = [obj.matrix_world @ v for v in frame]
# move into pixelspace
from bpy_extras.view3d_utils import location_3d_to_region_2d
region, rv3d = view3d_find(context)
frame_px = [location_3d_to_region_2d(region, rv3d, v) for v in frame]
return frame_px
# -> BASED ON: https://blender.stackexchange.com/a/31799/31447
def draw_string(x, y, packed_strings):
font_id = 0
blf.size(font_id, 18, 72)
x_offset = 0
y_offset = 0
line_height = (blf.dimensions(font_id, "M")[1] * 1.45)
for command in packed_strings:
if len(command) == 2:
pstr, pcol = command
blf.color(font_id, pcol[0], pcol[1], pcol[2], pcol[3]) # #bgl.glColor4f(pcol)
text_width, text_height = blf.dimensions(font_id, pstr)
blf.position(font_id, (x + x_offset), (y + y_offset), 0)
blf.draw(font_id, pstr)
x_offset += text_width
else:
x_offset = 0
y_offset -= line_height
def draw_callback_px(self, context):
WHITE = (1, 1, 1, .7)
CR = "Carriage Return"
x, y = view3d_camera_border(context)[3]
cam_ob = context.scene.camera
if cam_ob is not None:
ps = [
("{} {}mm".format(cam_ob.name, cam_ob.data.lens), WHITE),
CR,
CR,
("T: {:.2f}, {:.2f}, {:.2f}".format(
cam_ob.location.x,
cam_ob.location.y,
cam_ob.location.z), WHITE),
CR,
("R: {:.2f}, {:.2f}, {:.2f}".format(
cam_ob.rotation_euler.x,
cam_ob.rotation_euler.y,
cam_ob.rotation_euler.z), WHITE),
]
draw_string(x+10, y-20, ps)
# restore opengl defaults
bgl.glLineWidth(1)
bgl.glDisable(bgl.GL_BLEND)
# -> MODAL OPERATOR TEMPLATE
class ModalDrawOperator(bpy.types.Operator):
"""Draw a line with the mouse"""
bl_idname = "view3d.modal_operator"
bl_label = "Simple Modal View3D Operator"
@classmethod
def poll(cls, context):
return context.area.type == 'VIEW_3D'
def modal(self, context, event):
context.area.tag_redraw()
if event.type in {'RIGHTMOUSE', 'ESC'}:
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
return {'CANCELLED'}
return {'PASS_THROUGH'}
def invoke(self, context, event):
if context.space_data.region_3d.view_perspective == 'CAMERA':
# the arguments we pass the the callback
args = (self, context)
# Add the region OpenGL drawing callback
# draw in view space with 'POST_VIEW' and 'PRE_VIEW'
self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
else:
self.report({'WARNING'}, "Switch into Camera View")
return {'CANCELLED'}
def register():
bpy.utils.register_class(ModalDrawOperator)
def unregister():
bpy.utils.unregister_class(ModalDrawOperator)
if __name__ == "__main__":
register()
Copie y pegue el script en el editor de texto, ejecútelo, muévase a la Vista 3D, presione F3y escriba "Operador simple ..." para ejecutar. Si desea convertirlo en un complemento, simplemente agregue un diccionario de Python llamado "bl_info" en la parte superior de su complemento:https://wiki.blender.org/wiki/Process/Addons/Guidelines/metainfo
Para que funcione para las versiones 2.7x , tendría que reemplazar 2 líneas debido a los cambios en la Multiplicación de matrices y sobre cómo establecer el color del texto usando blf.color en las versiones más recientes:
# draw_string()
- blf.color(font_id, pcol[0], pcol[1], pcol[2], pcol[3]) # Blender 2.8x
+ bgl.glColor4f(*pcol) # Blender 2.7x
# view3d_camera_border()
- frame = [obj.matrix_world @ v for v in frame] # Blender 2.8x
+ frame = [obj.matrix_world * v for v in frame] # Blender 2.7x