19
$\begingroup$

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.add(4)
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.add(4)
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
#object_utils.object_data_add(bpy.context, mesh)

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)?

$\endgroup$
0

2 Answers 2

20
$\begingroup$

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

quads

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
scene.collection.objects.link(obj)
obj.select_set(True)
bpy.context.view_layer.objects.active = obj  # Set object as active
$\endgroup$
1
  • 5
    $\begingroup$ With Blender 2.8, I had to replace scene.objects.link() with scene.collection.objects.link() to make this work. $\endgroup$
    – kakyo
    Jul 8, 2019 at 2:40
8
$\begingroup$

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.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .