4
$\begingroup$

I am working on a Python script on Blender and I need the location of the focus point of the active camera. I know we can display the limits of a camera but I can't manage to get the exact position of the focus point using Python. Could you help me to find it ?

Here is an illustration with point of focus display (Yellow cross) :Point of Focus (yellow cross)

$\endgroup$

1 Answer 1

6
$\begingroup$

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
$\endgroup$
1
  • $\begingroup$ Thank you, I manage to run this following script, using yours. Selecting my camera and generate a 'b' empty object at the Focus Point Position : import bpy import bgl from mathutils import Vector from mathutils.geometry import intersect_point_line from math import * Focus_pt = bpy.context.object.matrix_world*Vector((0,0,-bpy.context.object.data.dof_distance)) bpy.ops.object.add(type='EMPTY') bpy.context.active_object.name = 'b' bpy.context.active_object bpy.data.objects["b"] b = bpy.data.objects['b'] b.location[0] = Focus_pt.x b.location[1] = Focus_pt.y b.location[2] = Focus_pt.z $\endgroup$
    – Grégoire
    Commented Jun 19, 2014 at 8:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .