# Selecting a face in a script so that you can edit eg resize it?

I was trying to write a script to generate an object from primitives but came across a problem I couldn't solve. The code generates a cylinder and finds the face as well as putting it into edit mode. However when I try and select it in edit mode the whole object is still selected.
How do I script the selection of just that face?
When I do it by hand the selection of the face which I can do generates nothing in the info window.

import bpy

ob = bpy.data.objects['Cylinder']
ob.name = 'NewCylinder'
mesh = ob.data

bpy.ops.object.mode_set(mode = 'EDIT')
n = 0
for face in mesh.polygons:
face.select = False
if len(face.vertices) > 4:
print(' end face {}'.format(n))
n += 1
if n == 2:
face.select = True
bpy.ops.transform.resize(value=(0.33, 0.33, 0.33))


It might seem counter-intuitive, but you need to be in Object mode to change the selection when using .mesh. I changed a few more things, like you can use the 'DESELECT' action in mesh.select_all else edges are still selected when you try to un-select faces

import bpy

ob = bpy.context.object  # gets a reference to the newly created object
ob.name = 'NewCylinder'
mesh = ob.data

bpy.ops.mesh.select_all(action='DESELECT')

bpy.ops.object.mode_set(mode = 'OBJECT')
n = 0
for face in mesh.polygons:
if len(face.vertices) > 4:
n += 1
if n == 2:
face.select = True

bpy.ops.object.mode_set(mode = 'EDIT')
bpy.ops.transform.resize(value=(0.33, 0.33, 0.33))


• Noteworthy: bpy.context.object should be used after calling a mesh primitive operator to refer to the newly created object (like zeffii did). You might pick the wrong object otherwise if the name already existed. – CodeManX Aug 9 '15 at 19:03
• @CoDEmanX i'll add that as a comment into the code too – zeffii Aug 9 '15 at 19:28
• (Sorry for the comment but @zeffi I am delighted with the solution and stackexchange. I racked my head about this for 1 day) – hum3 Aug 9 '15 at 23:13
• @hum3, as you can see by the other answer there's a variety of approaches to this. My preference is the bmesh method shown by CoDEmanX, but I wanted to provide an answer that shared more with your original question - to keep the point of reference. – zeffii Aug 10 '15 at 5:06
• @zeffi I know that I ought to learn the bmesh route but I am just starting and this matched using the info window like a macro recorder. – hum3 Aug 11 '15 at 7:04

You could also do this with Bmesh module, which does not require mode switches:

import bpy
import bmesh
from mathutils import Matrix

scene = bpy.context.scene

bm = bmesh.new()
bmesh.ops.create_cone(bm, cap_ends=True, segments=32, diameter1=1, diameter2=1, depth=2)

caps = [f for f in bm.faces if len(f.verts) > 4]
bottom_cap = min(caps, key=lambda f: f.verts[0].co.z)

mat = Matrix.Identity(4)
mat[0][0] = 1/3
mat[1][1] = 1/3
mat[2][2] = 1
bmesh.ops.transform(bm, matrix=mat, verts=bottom_cap.verts)

me = bpy.data.meshes.new("Cylinder")
bm.to_mesh(me)
me.update()

ob = bpy.data.objects.new("NewCylinder", me)
ob.location = scene.cursor_location

BTW: The same result (with bottom face scaled down by 1/3) can also be achieved with a single call to create_cone():
# diameter1 controls the size of the bottom cap