def new_stimulus(stim_id):
    scene = bpy.data.scenes["Scene"]

    # create the first cube
    bpy.ops.mesh.primitive_cube_add()
    cube = bpy.data.objects["Cube"]

    # add a bevel to the cube object
    cube.select = True
    bpy.ops.object.editmode_toggle()
    bpy.ops.mesh.bevel(offset_type='PERCENT', offset=3, segments=15)
    bpy.ops.object.editmode_toggle()
    cube.select = False

    # parse the stim id into block locations
    block_locs = utils.parse_stim_id(stim_id)
    cube.location = block_locs[0]

    # create copies of the cube to form the full stimulus
    blocks = [cube]
    for i in range(1, len(block_locs)):
        name = "block_{:02d}".format(i)
        mesh = bpy.data.meshes.new(name)
        ob_new = bpy.data.objects.new(name, mesh)
        ob_new.data = cube.data.copy()
        ob_new.data.name = "{}_data".format(name)
        ob_new.scale = cube.scale
        ob_new.location = block_locs[i]
        scene.objects.link(ob_new)
        blocks.append(ob_new)

    # join the blocks together
    bpy.ops.object.select_all(action='DESELECT')
    for block in blocks:
        block.select = True
    bpy.context.scene.objects.active = blocks[-1]
    bpy.ops.object.join()

    # remove double vertices
    bpy.ops.object.editmode_toggle()
    bpy.ops.mesh.remove_doubles()
    bpy.ops.object.editmode_toggle()

    # reset the center to center of mass, and move to the origin
    stim = bpy.context.scene.objects.active
    bpy.context.scene.cursor_location = (0, 0, 0)
    bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
    assert list(stim.location) == [0, 0, 0]

    # set the new name
    stim.name = stim_id
    stim.data.name = stim_id

    # add it to the scene
    scene = bpy.data.scenes["Scene"]
    scene.objects.active = stim
    stim.select = True

    return stim
    sides = [[0, 0], [0, 90], [0, 180], [0, 270], [90, 0], [270, 0]]
    rots = itertools.product(sides, range(0, 360, 20))
    for (x_rot, z_rot), y_rot in rots:

        # create a seed based on the stimulus id, so we will always pick the same
        # color for a given stimulus
        seed = int(str(np.abs(hash(stim_id[2:])))[:9])
        np.random.seed(seed)

        # generate the color
        rgb = [int(x * 255) for x in hls_to_rgb(np.random.rand(), 0.5, 0.6)]
        color = "#{:02x}{:02x}{:02x}".format(*rgb)

        # figure out the camera position
        block_locs = utils.parse_stim_id(stim_id)
        new_block_locs = rotate_xyz(block_locs, x_rot, z_rot, y_rot)
        z_locs = new_block_locs[:, 2]
        y_trans = cam_look = ((np.max(z_locs) - np.min(z_locs)) / 2.0) + 1

        # render the template
        scene = template.render(
            stim_id=stim_id, color=color, cam_look=cam_look, x_rot=x_rot, y_rot=y_rot, z_rot=z_rot, y_trans=y_trans
        )

        # save it out to file
        scene_name = "{}_xrot_{:03d}_zrot_{:03d}_yrot_{:03d}.xml".format(stim_id, x_rot, z_rot, y_rot)
        scene_path = os.path.join("stimuli", "scene", stim_id, scene_name)
        print(scene_path)
        with open(scene_path, "w") as fh:
            fh.write(scene)