Add Cuboid Addon
If you know you want to add a 3 x 4 x 5 subdivided cuboid, it might be easier to set this when the object is created, rather than have to add a cube and then go thru the rigmarole of subdividing on each axis.
Here's a script based on the text editor > templates > python > Addon
Add Object example in blender. Adds a cube with bmesh, and subdivides it into dimensions.

Example of adding cuboid in edit mode (pretty crappy gif)`
EDIT for 2.8
bl_info = {
"name": "Add i x j x k Cuboid",
"author": "batFINGER",
"version": (1, 1),
"blender": (2, 81, 0),
"location": "View3D > Add > Mesh > Cuboid",
"description": "Adds an i x j x k Cuboid",
"warning": "",
"wiki_url": "",
"category": "Add Mesh",
}
import bpy
import bmesh
from bpy.types import Operator
from bpy.props import FloatVectorProperty, IntVectorProperty
from bpy_extras.object_utils import AddObjectHelper, object_data_add
from mathutils import Matrix
def add_object(self, context):
bm = bmesh.new()
mesh = bpy.data.meshes.new(name="Cuboid")
S = Matrix.Scale(1, 4)
for i in range(3):
S[i][i] = self.scale[i] * self.dimensions[i]
bmesh.ops.create_cube(bm, size=1, matrix=S)
#bm.edges.ensure_lookup_table()
axes = [axis for axis in Matrix().to_3x3()]
for cuts, axis in zip(self.dimensions, axes):
def aligned(e):
dir = (e.verts[1].co - e.verts[0].co).normalized()
return abs(dir.dot(axis)) > 0.5
if cuts == 1:
continue
bmesh.ops.subdivide_edges(bm,
edges=[e for e in bm.edges if aligned(e)],
use_grid_fill=True,
cuts=cuts - 1)
for v in bm.verts:
v.select = True
bm.select_flush(True)
bm.to_mesh(mesh)
#mesh.update()
object_data_add(context, mesh, operator=self)
bm.free()
if context.edit_object:
mesh = context.edit_object.data
bmesh.from_edit_mesh(mesh)
bmesh.update_edit_mesh(mesh)
class MESH_OT_add_cuboid(Operator, AddObjectHelper):
"""Create a subdivided by dimension cuboid"""
bl_idname = "mesh.add_cuboid"
bl_label = "Cuboid"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def description(cls, context, event):
return "Create a i x j x k Cuboid"
dimensions : IntVectorProperty(
name="Unit Dimensions",
default=(1, 1, 1),
description="Width(x) x Breadth(y) x Height(z)",
min=1,
max=20
)
scale : FloatVectorProperty(
name="scale",
default=(1.0, 1.0, 1.0),
subtype='TRANSLATION',
description="scaling",
)
def execute(self, context):
add_object(self, context)
return {'FINISHED'}
# Registration
def add_object_button(self, context):
self.layout.operator(
MESH_OT_add_cuboid.bl_idname, icon='MESH_CUBE')
def register():
bpy.utils.register_class(MESH_OT_add_cuboid)
bpy.types.VIEW3D_MT_mesh_add.append(add_object_button)
def unregister():
bpy.utils.unregister_class(MESH_OT_add_object)
bpy.utils.unregister_manual_map(add_object_manual_map)
bpy.types.VIEW3D_MT_mesh_add.remove(add_object_button)
if __name__ == "__main__":
register()
# test call
bpy.ops.mesh.add_cuboid(dimensions=(3, 4, 5))
EDIT. Change axis test on edges to a simple dot product. Using bmesh.ops.similar_edges(...)
becomes unreliable when scrubbing props in operator panel. New mesh vertices are selected in edit mode.