How to create a mesh programmatically, without bmesh?

I do not want to use BMesh this time.

I want to create a mesh programmatically, for this purpose I created this short script to see what I do wrong in my importer script. In this script I try to create a tetraeder. First I create the mesh, then define the vertices. Then I go for the polygons, but here I do something bad, because at the end I got no polygons defined.

The code:

mesh = bpy.data.meshes.new("Teszt")

mesh.vertices[0].co = (0,0,0)
mesh.vertices[1].co = (2,0,0)
mesh.vertices[2].co = (1,2,0)
mesh.vertices[3].co = (1,1,3)

mesh.polygons[0].vertices = (0,1,2)
mesh.polygons[1].vertices = (0,1,3)
mesh.polygons[2].vertices = (1,2,3)

mesh.polygons[3].vertices = (0,2,3)
print(len(mesh.polygons[3].vertices))

mesh.polygons[3].vertices = [0,2,3]
print(len(mesh.polygons[3].vertices))

#mesh.update()

#from bpy_extras import object_utils


I am pretty new to Python, so it may be totally my fault, but when I check the len of (0,2,3), that is 3, when I execute mesh.polygons[3].vertices = (0,2,3) it says 0. No exception or error message, just shallows it.

When I try to update() or ...data_add( at the end, Blender simply exits.

So my question is: how to define the polygons properly (and without using bmesh)?

Your importer script might be easier to write using from_pydata, it will certainly look cleaner.

verts = [
(1.0, 1.0, -1.0),
(1.0, -1.0, -1.0),
(-1.0, -1.0, -1.0),
(-1.0, 1.0, -1.0),
(1.0, 1.0, 1.0),
(1.0, -1.0, 1.0),
(-1.0, -1.0, 1.0),
(-1.0, 1.0, 1.0)
]

faces = [
(0, 1, 2, 3),
(4, 7, 6, 5),
(0, 4, 5, 1),
(1, 5, 6, 2),
(2, 6, 7, 3),
(4, 0, 3, 7)
]


tris

verts = [
(-0.285437,-0.744976,-0.471429),
(-0.285437,-0.744976,-2.471429),
(1.714563,-0.744976,-2.471429),
(1.714563,-0.744976,-0.471429),
(-0.285437,1.255024,-0.471429),
(-0.285437,1.255024,-2.471429),
(1.714563,1.255024,-2.471429),
(1.714563,1.255024,-0.471429)
]

faces =  [
(4,5,1), (5,6,2), (6,7,3), (4,0,7),
(0,1,2), (7,6,5), (0,4,1), (1,5,2),
(2,6,3), (7,0,3), (3,0,2), (4,7,5)
]


both

import bpy

# verts =
# faces =

mesh_data = bpy.data.meshes.new("cube_mesh_data")
mesh_data.from_pydata(verts, [], faces)
mesh_data.update()

obj = bpy.data.objects.new("My_Object", mesh_data)

scene = bpy.context.scene

• With Blender 2.8, I had to replace scene.objects.link() with scene.collection.objects.link() to make this work. – kakyo Jul 8 '19 at 2:40
The reason the script fails is because you're not adding loops or setting the loop start or loop_total for each polygon.
This is not very handy for mesh creation, which is why BMesh API was added as well as from_pydata utility function.
If you want to see how it works bpy_types.py defines the from_pydata function.