Vista 3D - Come visualizzare i dati della telecamera nella cornice della telecamera?
Esiste un modo per utilizzare opzioni di visualizzazione come "info oggetto" o "nome vista" (nelle preferenze del viewport) per visualizzare altre informazioni come ad esempio la focale lenth della telecamera attiva e la sua posizione. E c'è un modo per spostare queste informazioni ovunque nella finestra 3D? Come in questo esempio:

Così ho trovato uno script che mi permette di visualizzare il punto focale sulla finestra 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)

La prima riga 3 mi permette di cancellare il display precedente. Come posso impedire allo scipte di leggere le prime 3 righe la prima volta che lo script viene eseguito? Per ora il copione legge una volta la focale e la scrive. Come assicurarsi che lo script venga letto ogni volta che viene cambiata la focale?
Risposte
AFAIK questo non è possibile per impostazione predefinita e immagino che non esista alcun componente aggiuntivo in grado di visualizzare alcun tipo di informazione nella cornice della fotocamera.
Tuttavia, puoi disegnare il testo usando il modulo bgl di python e creare il tuo add-on. Il seguente codice di esempio si basa sul nostro famoso modello Operator Modal Draw fornito con Blender, esteso dalle risposte da Coordinate of corner of camera view border e Multi-line Text in blf (with multi color option) to get the ball rolling:

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()
Copiare e incollare lo script nell'editor di testo, eseguirlo, passare alla vista 3D, premere F3e digitare "Operatore semplice ..." per eseguire. Se desideri convertirlo in un componente aggiuntivo, aggiungi un dizionario Python denominato "bl_info" nella parte superiore del tuo componente aggiuntivo:https://wiki.blender.org/wiki/Process/Addons/Guidelines/metainfo
Per farlo funzionare per le versioni 2.7x dovresti sostituire 2 righe a causa dei cambiamenti in Matrix Multiplication e su come impostare il colore del testo usando blf.color nelle versioni più recenti:
# 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