2
$\begingroup$

Is it possible to change the camera in the 3d-viewport to something a little more camera-ish. For example in maya the camera looks like this: camera

Can this be done with python scripting?

$\endgroup$
0

3 Answers 3

3
$\begingroup$

You can overlay the 3D Viewport using a draw handler.

Use 'PRE_VIEW' to have it in world space behind everything else, 'POST_VIEW' for world space like a real object (depth test). 'POST_PIXEL' is screen-space on top of everything else, but requires 2D coordinates.

You would need to hide the real camera however, which is drawn by C code - maybe put it on another layer or simply hide it? Note that you can't move the camera while it's hidden.

Proof of concept:

import bpy
import bgl
import blf
from mathutils import Vector

bbox_normal = ((-1.0, -1.0, -1.0), (-1.0, -1.0, 1.0), (-1.0, 1.0, 1.0), (-1.0, 1.0, -1.0), (1.0, -1.0, -1.0), (1.0, -1.0, 1.0), (1.0, 1.0, 1.0), (1.0, 1.0, -1.0))

def draw_callback_px(self, context):
    if context.scene.camera is None:
        return

    font_id = 0  # XXX, need to find out how best to get this.

    # 50% alpha, 2 pixel width line
    bgl.glEnable(bgl.GL_BLEND)
    bgl.glColor4f(1.0, 0.0, 0.0, 0.5)
    bgl.glLineWidth(2)

    bbox = [context.scene.camera.matrix_world * Vector(x) for x in bbox_normal]

    bgl.glBegin(bgl.GL_LINE_STRIP)
    bgl.glVertex3f(*bbox[0])
    bgl.glVertex3f(*bbox[1])
    bgl.glVertex3f(*bbox[2])
    bgl.glVertex3f(*bbox[3])
    bgl.glVertex3f(*bbox[0])
    bgl.glVertex3f(*bbox[4])
    bgl.glVertex3f(*bbox[5])
    bgl.glVertex3f(*bbox[6])
    bgl.glVertex3f(*bbox[7])
    bgl.glVertex3f(*bbox[4])
    bgl.glEnd()

    bgl.glBegin(bgl.GL_LINES)
    bgl.glVertex3f(*bbox[1])
    bgl.glVertex3f(*bbox[5])
    bgl.glVertex3f(*bbox[2])
    bgl.glVertex3f(*bbox[6])
    bgl.glVertex3f(*bbox[3])
    bgl.glVertex3f(*bbox[7])
    bgl.glEnd()


    # 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', 'PRE_VIEW')
            if context.scene.camera:
                context.scene.camera.hide = True
            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':
            ctx = bpy.context.copy()
            ctx['area'] = area
            bpy.ops.view3d.modal_operator(ctx, 'INVOKE_DEFAULT')
            break

To draw the box on top of everything else (like X-ray):

from bpy_extras.view3d_utils import location_3d_to_region_2d

# ...

    bbox = []
    region = context.region
    rv3d = context.space_data.region_3d
    for x in bbox_normal:
        coord = context.scene.camera.matrix_world * Vector(x)
        bbox.append(tuple(map(round, location_3d_to_region_2d(region, rv3d, coord))))

    bgl.glBegin(bgl.GL_LINE_STRIP)
    bgl.glVertex2i(*bbox[0]) # must be 2i for 2D integer values!

    # ...
$\endgroup$
3
  • $\begingroup$ For me POST_VIEW acts normally (visible when in front of objects, and occluded when behind objects). PRE_VIEW is always occluded, even when in front of objects. POST_PIXEL seems to be invisible.. $\endgroup$
    – gandalf3
    Jun 5, 2014 at 19:58
  • $\begingroup$ You're right, PRE_VIEW is behind all objects, POST_VIEW is like a real object. For POST_PIXEL you need 2D region coords. See my edit above. $\endgroup$
    – CodeManX
    Jun 5, 2014 at 20:16
  • $\begingroup$ I see that the only way to get exactly what I would like would be writing some c++ code. However, with some modification this could be pretty close. The actual camera could be the lens(witch would allow the user to select the camera) and the 'body' would be added on. The only thing remaining is to allow the user to select the 'body' of the camera and have the camera object be selected. Perhaps this could be made into an add-on. $\endgroup$
    – Isaac
    Jun 6, 2014 at 2:37
1
$\begingroup$

You can make objects cameras, so you could model a camera mesh and set it as the camera with Ctrl0 (Numpad). If you delete all the faces in edit mode (X > Only Faces), it won't show up in a render, but will still show up as a wireframe in the viewport.

$\endgroup$
1
  • $\begingroup$ In addition to not having the camera settings, this doesn't seem to work for rendering (cycles renders transparent images and BI spews artifacts which look a bit like z-fighting everywhere), but perhaps you could do something with parenting a hidden camera to a custom object, so moving the object would move the camera, but a normal camera is still used? Perhaps with some kind of two way constraint so that moving the camera also moves the custom object? $\endgroup$
    – gandalf3
    Jun 5, 2014 at 19:47
0
$\begingroup$

This feature is (intentionally) not supported.

If you want to so this you could make a mesh a parent/child of the camera, or use some OpenGL tricks, but to change this you really would have to change Blender's source code.

$\endgroup$

You must log in to answer this question.

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