Tampilan 3d - Bagaimana cara menampilkan data kamera dalam bingkai kamera?
Apakah ada cara untuk menggunakan opsi tampilan seperti "info objek" atau "nama tampilan" (dalam preferensi viewport) untuk menampilkan informasi lain seperti misalnya fokus lenth kamera aktif dan posisinya. Dan apakah ada cara untuk memindahkan informasi ini ke mana pun di jendela 3d? Seperti contoh berikut:

Jadi saya menemukan skrip yang memungkinkan saya menampilkan titik fokus pada jendela 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)

3 baris pertama memungkinkan saya untuk menghapus tampilan sebelumnya. Bagaimana cara mencegah scipte membaca 3 baris pertama saat pertama kali menjalankan skrip? Untuk saat ini skrip membaca fokus satu kali dan menulisnya. Bagaimana cara memastikan bahwa skrip dibaca setiap kali fokus diubah?
Jawaban
AFAIK itu tidak mungkin secara default dan saya kira tidak ada add-on yang mampu menampilkan segala jenis informasi dalam bingkai kamera.
Namun, Anda dapat menggambar teks menggunakan modul bgl python dan membuat pengaya Anda sendiri. Kode contoh berikut didasarkan pada template Operator Modal Draw kami yang terkenal yang dilengkapi dengan blender, diperluas oleh jawaban dari Koordinat sudut batas tampilan kamera dan Teks Multi-baris dalam blf (dengan opsi multi warna) untuk menggulirkan bola:

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()
Salin dan tempel skrip ke editor teks, jalankan, pindah ke Tampilan dalam 3d, tekan F3dan ketik "Operator Sederhana ..." untuk mengeksekusi. Jika Anda ingin mengubahnya menjadi Add-on, cukup tambahkan kamus python bernama "bl_info" di bagian atas addon Anda:https://wiki.blender.org/wiki/Process/Addons/Guidelines/metainfo
Untuk membuatnya berfungsi untuk versi 2.7x Anda harus mengganti 2 baris karena perubahan dalam Perkalian Matriks dan tentang cara mengatur warna teks menggunakan blf.color di versi yang lebih baru:
# 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