What is a good way to create polygons via python?

I’m writing a script that will read data from a file, and use the data to create a polygon.
There isn’t a way to from the user menu to create an n-sided polygon, at least not from what I can tell. I also did not find a way to create one in the Blender python API. Any suggestions or secret workarounds?

There’s actually the built-in Add > Mesh > Circle opeator:

bpy.ops.mesh.primitive_circle_add(vertices=7, radius=1, fill_type=‘NGON’, location=(0, 0, 0), rotation=(0, 0, 0))

And with python, there are at least 2 ways. I recommend using the bmesh module, as you won’t need to deal with loops and stuff yourself:
http://www.blender.org/documentation/blender_python_api_2_68_5/bmesh.html

Here’s an example script:

import bpy
import bmesh
from math import *
from mathutils import Vector
from bpy.props import IntProperty, FloatProperty

def main(self, context):
    step = self.angle_max / self.segments
    
    if context.mode == 'EDIT_MESH':
        ob = context.object
        bm = bmesh.from_edit_mesh(ob.data)
        offset = context.scene.cursor_location - ob.location
    else:
        bm = bmesh.new()
        offset = Vector()
    
    verts = []
    verts.append(bm.verts.new(offset))
    
    angle = 0
    for i in range(self.segments):
        rad = radians(angle)
        verts.append(bm.verts.new((sin(rad)*self.radius+offset.x, cos(rad)*self.radius+offset.y, offset.z)))
        angle += step
    rad = radians(self.angle_max)
    verts.append(bm.verts.new((sin(rad)*self.radius+offset.x, cos(rad)*self.radius+offset.y, offset.z)))

        
    faces = [bm.faces.new(verts)]
    
    if self.thickness != 0.0:
        geom = bmesh.ops.extrude_face_region(bm, geom=faces)
        verts_extruded = [v for v in geom['geom'] if isinstance(v, bmesh.types.BMVert)]
        bmesh.ops.translate(bm, verts=verts_extruded, vec=(0,0,self.thickness))
        verts.extend(verts_extruded)
    
    bm.normal_update()
        
    if bm.is_wrapped:
        bpy.ops.mesh.select_all(action='DESELECT')
        
    for v in verts:
        v.select = True
    bm.select_flush(True)
    
    if bm.is_wrapped:
        bmesh.update_edit_mesh(context.object.data)
    else:
        me = bpy.data.meshes.new("CircleSegment")
        bm.to_mesh(me)
        ob = bpy.data.objects.new("CircleSegment", me)
        ob.location = context.scene.cursor_location
        if bpy.ops.object.select_all.poll():
            bpy.ops.object.select_all(action="DESELECT")
        bpy.context.scene.objects.link(ob)
        bpy.context.scene.objects.active = ob
        ob.select = True
        bpy.context.scene.update()
    


class MESH_OT_primitive_circle_segment_add(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "mesh.primitive_circle_segment_add"
    bl_label = "Add Circle Segment"
    bl_options = {'REGISTER', 'UNDO'}
    
    segments = IntProperty(name="Segments", min=1, soft_max=50, default=6)
    angle_max = IntProperty(name="Segment angle", min=1, max=359, default=90, subtype='ANGLE')
    radius = FloatProperty(name="Radius", min=0.01, soft_max=100, default=5, step=10)
    thickness = FloatProperty(name="Thickness", soft_min=-100, soft_max=100, default=1, step=10)

    @classmethod
    def poll(cls, context):
        return True

    def execute(self, context):
        main(self, context)
        return {'FINISHED'}

def register():
    bpy.utils.register_module(__name__)


def unregister():
    bpy.utils.unregister_module(__name__)


if __name__ == "__main__":
    register()


Thanks for the reply.
I should have been more precise about what I am trying to do - an irregular polygon is what I’m trying to create - something like this


but with far more points.

(image is much larger than needed)

Simplified script that actually creates that shape:

import bpy, bmesh

verts = ((0, 3),(2.5, 0.5),(5, 1),(4.5, 3.5),(10.5, 2),(8, 10),(7, 4.5),(2, 6))

bm = bmesh.new()
for v in verts:
    bm.verts.new((v[0], v[1], 0))
bm.faces.new(bm.verts)

bm.normal_update()

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

ob = bpy.data.objects.new("", me)
bpy.context.scene.objects.link(ob)
bpy.context.scene.update()

Thank you. Once I get the json to python objects script working, I’ll use the sample you provided - it looks like it will do exactly what I need!

This is working near perfect. Some of the faces are not being created correctly - I need to look into that.
One thing I am not able to figure out is to set the origin of the mesh. By default it is at 0,0,0 - but I would like to change it to the MEDIAN, which I attempted to do, but was not successful. (I don’t have the script with me, but it was bpy.ops… pivot point??? ).
I did it manually in the UI and then copied the same function and placed it in the script.

bpy.ops.object.origin_set(type=‘ORIGIN_GEOMETRY’, center=‘MEDIAN’)

but beware, IIRC the behavior differs in object and editmode. You could also transform the mesh with bmesh module (translation matrix) and change the object’s location - same effect. But you need to calculate the median first of course.

That’s the function I’m calling with those parameters - but the origin is not moving to the ‘median’ of the object.

Never mind, found one of your other posts and figured it out.
Needed to select the object first in the scene.