The following script calculates the clip start, end and dof distance locations and visualizes them in the viewport (like the Limits option for cameras), the rotation mode does not matter:
import bpy
import bgl
from mathutils import Vector
from mathutils.geometry import intersect_point_line
def is_camera(ob):
return ob is not None and ob.type == 'CAMERA'
def draw_callback_px(self, context):
sce = context.scene
if is_camera(context.object):
cam_ob = context.object
elif is_camera(sce.camera):
cam_ob = sce.camera
else:
return
mat = cam_ob.matrix_world
cam = cam_ob.data
start = mat * Vector((0, 0, -cam.clip_start))
end = mat * Vector((0, 0, -cam.clip_end))
if cam.dof_object is None:
dof_loc = mat * Vector((0, 0, -cam.dof_distance))
else:
pt = cam.dof_object.matrix_world.translation
line_p1 = mat.translation
line_p2 = mat * Vector((0, 0, -1))
loc = intersect_point_line(pt, line_p1, line_p2)
dof_loc = loc[0]
# 80% alpha, 2 pixel width line
bgl.glEnable(bgl.GL_BLEND)
bgl.glLineWidth(2)
#sce.cursor_location = dof_loc
def line(color, start, end):
bgl.glColor4f(*color)
bgl.glBegin(bgl.GL_LINES)
bgl.glVertex3f(*start)
bgl.glVertex3f(*end)
bgl.glEnd()
line((1.0, 0.0, 0.0, 0.8), start, dof_loc)
line((0.0, 0.0, 1.0, 0.8), dof_loc, end)
# restore opengl defaults
bgl.glLineWidth(1)
bgl.glDisable(bgl.GL_BLEND)
bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
class ModalDrawOperator(bpy.types.Operator):
"""Draw a line with the mouse"""
bl_idname = "view3d.modal_operator"
bl_label = "Simple Modal View3D Operator"
def modal(self, context, event):
context.area.tag_redraw()
if event.type == 'ESC':
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
return {'CANCELLED'}
return {'PASS_THROUGH'}
def invoke(self, context, event):
if context.area.type == 'VIEW_3D':
# 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_VIEW')
context.window_manager.modal_handler_add(self)
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()
for area in bpy.context.screen.areas:
if area.type == 'VIEW_3D':
bpy.ops.view3d.modal_operator({'area': area}, 'INVOKE_DEFAULT')
break