I assume you refer to axis-aligned bounding boxes (AABB), because regular bounding boxes are a built-in feature.
You can use draw handlers to draw in supported spaces with OpenGL (bgl module). draw_handler_add() is not documented, but you can find examples in Text Editor, Templates menu.
Here's a modified version of my bound box draw handler:
import bpy
import bgl
from mathutils import Vector
def draw_poll(ob):
return ob is not None and ob.type in ('MESH', 'CURVE', 'SURFACE', 'META', 'FONT')
def draw_callback_view(self, context):
for ob in context.selected_objects:
if not draw_poll(ob):
return
mat = ob.matrix_world
# 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 = [mat * Vector(b) for b in ob.bound_box]
min_x = min(b.x for b in bbox)
max_x = max(b.x for b in bbox)
min_y = min(b.y for b in bbox)
max_y = max(b.y for b in bbox)
min_z = min(b.z for b in bbox)
max_z = max(b.z for b in bbox)
if ob == context.object:
bgl.glColor4f(*self._color1)
else:
bgl.glColor4f(*self._color2)
bgl.glBegin(bgl.GL_LINE_STRIP)
bgl.glVertex3f(min_x, min_y, min_z)
bgl.glVertex3f(min_x, max_y, min_z)
bgl.glVertex3f(max_x, max_y, min_z)
bgl.glVertex3f(max_x, min_y, min_z)
bgl.glVertex3f(min_x, min_y, min_z)
bgl.glVertex3f(min_x, min_y, max_z)
bgl.glVertex3f(min_x, max_y, max_z)
bgl.glVertex3f(max_x, max_y, max_z)
bgl.glVertex3f(max_x, min_y, max_z)
bgl.glVertex3f(min_x, min_y, max_z)
bgl.glEnd()
bgl.glBegin(bgl.GL_LINES)
bgl.glVertex3f(max_x, min_y, min_z)
bgl.glVertex3f(max_x, min_y, max_z)
bgl.glVertex3f(min_x, max_y, min_z)
bgl.glVertex3f(min_x, max_y, max_z)
bgl.glVertex3f(max_x, max_y, min_z)
bgl.glVertex3f(max_x, max_y, max_z)
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 in {'ESC'}:
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
self._handle = None
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'
theme = context.user_preferences.themes[0]
self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_view, args, 'WINDOW', 'POST_VIEW')
self._color1 = theme.view_3d.object_active[:] + (0.5,)
self._color2 = theme.view_3d.object_selected[:] + (0.5,)
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':
context = bpy.context.copy()
context['area'] = area
bpy.ops.view3d.modal_operator(context, 'INVOKE_DEFAULT')
break